16. EPMO Open Source Coordination Office Redaction File Detail Report

Produced by Araxis Merge on 8/14/2018 11:32:38 AM Eastern Daylight 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-2018-06-18.zip\cbs\src\main\java\gov\va\cpss\jasper PdfPatientStatementFactoryService.java Tue Jun 19 13:45:28 2018 UTC
2 cbs-2018-06-18.zip\cbs\src\main\java\gov\va\cpss\jasper PdfPatientStatementFactoryService.java Mon Aug 13 20:23:51 2018 UTC

16.2 Comparison summary

Description Between
Files 1 and 2
Text Blocks Lines
Unchanged 2 2230
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   D N   
  50    */
  51   @SuppressW arnings({" nls", "sta tic-method "})
  52   public cla ss PdfPati entStateme ntFactoryS ervice {
  53  
  54           pr ivate stat ic final L ogger logg er = Logge r.getLogge r(PdfPatie ntStatemen tFactorySe rvice.clas s.getCanon icalName() );
  55  
  56           pr ivate Clas sLoader cl assLoader  = PdfPatie ntStatemen tFactorySe rvice.clas s.getClass Loader();
  57  
  58           //  AITC temp late speci fies that  the first  page shoul d not have  more than
  59           //  this many  lines.
  60           pr ivate stat ic final i nt MAX_LEN GTH_FIRST_ PAGE = 22;
  61  
  62           //  And the s ubsequent  pages shou ld not hav e more tha n this man y lines.
  63           pr ivate stat ic final i nt MAX_LEN GTH_EXTENS ION_PAGE =  39;
  64  
  65           //
  66           //  The accou nt number  is split o n the repo rt.
  67           //
  68           //  First 3 d igits / ch aracters f or Facilit y / Statio n Number
  69           pr ivate stat ic final i nt ACCOUNT _NUMBER_SP LIT_LENGTH _1 = 3;
  70           pr ivate stat ic final i nt ACCOUNT _NUMBER_SP LIT_POSITI ON_1 = 0;
  71  
  72           //  Fix for D efect 6164 42
  73           //  - Reforma t Account  Number
  74           //  Yiping Ya o - 01/30/ 2018
  75  
  76           //  DFN 1st 4  digits
  77           pr ivate stat ic final i nt ACCOUNT _NUMBER_SP LIT_LENGTH _2 = 4;
  78           pr ivate stat ic final i nt ACCOUNT _NUMBER_SP LIT_POSITI ON_2 = ACC OUNT_NUMBE R_SPLIT_PO SITION_1 +
  79                                                                                                                                          ACCOUNT _NUMBER_SP LIT_LENGTH _1;
  80           // private st atic final  int ACCOU NT_NUMBER_ SPLIT_LENG TH_2 = 3;
  81  
  82           //  DFN 2nd 4  digits
  83           pr ivate stat ic final i nt ACCOUNT _NUMBER_SP LIT_LENGTH _3 = 4;
  84           pr ivate stat ic final i nt ACCOUNT _NUMBER_SP LIT_POSITI ON_3 = ACC OUNT_NUMBE R_SPLIT_PO SITION_2 +
  85                                                                                                                                          ACCOUNT _NUMBER_SP LIT_LENGTH _2;
  86           // private st atic final  int ACCOU NT_NUMBER_ SPLIT_POSI TION_3 = 6 ;
  87           // private st atic final  int ACCOU NT_NUMBER_ SPLIT_LENG TH_3 = 3;
  88  
  89           //  DFN last  5 digits
  90           pr ivate stat ic final i nt ACCOUNT _NUMBER_SP LIT_LENGTH _4 = 5;
  91           pr ivate stat ic final i nt ACCOUNT _NUMBER_SP LIT_POSITI ON_4 = ACC OUNT_NUMBE R_SPLIT_PO SITION_3 +
  92                                                                                                                                          ACCOUNT _NUMBER_SP LIT_LENGTH _3;
  93           // private st atic final  int ACCOU NT_NUMBER_ SPLIT_POSI TION_4 = 9 ;
  94           // private st atic final  int ACCOU NT_NUMBER_ SPLIT_LENG TH_4 = 4;
  95  
  96           //  Last Name  1st 5 cha racters
  97           pr ivate stat ic final i nt ACCOUNT _NUMBER_SP LIT_LENGTH _5 = 5;
  98           pr ivate stat ic final i nt ACCOUNT _NUMBER_SP LIT_POSITI ON_5 = ACC OUNT_NUMBE R_SPLIT_PO SITION_4 +
  99                                                                                                                                          ACCOUNT _NUMBER_SP LIT_LENGTH _4;
  100           //  The lengt h of this  is optiona l, dependi ng on the  length of  last name.
  101           // private st atic final  int ACCOU NT_NUMBER_ SPLIT_POSI TION_5 = 1 3;
  102  
  103           //  String co nstant cha racters
  104           pr ivate stat ic final S tring STRI NG_SPACE =  " ";
  105           pr ivate stat ic final S tring STRI NG_DASH =  "-";
  106           pr ivate stat ic final S tring EMPT Y_STRING =  "";
  107  
  108  
  109           //  Dates on  report are  formatted  MM/dd/yyy y
  110           pr ivate stat ic final S tring REPO RT_DATE_FO RMAT = "MM /dd/yyyy";
  111  
  112           //  Number of  days to a dd to stat ement date  to get th e full pay ment date.
  113           pr ivate stat ic final i nt FULL_PA YMENT_DAY_ NUMBER_DEL TA = 25;
  114  
  115           //  Credit va lues have  trailing C R
  116           pr ivate stat ic final S tring CRED IT_SUFFIX  = "CR";
  117  
  118           //  HTML tag  / entity
  119           pr ivate stat ic final S tring HTML _LINE_BREA K = "<br/> ";
  120           pr ivate stat ic final S tring HTML _NON_BREAK ING_SPACE  = "&nbsp;" ;
  121  
  122           //  Property  / Tag Name s and Valu es
  123           pr ivate stat ic final S tring VA_L OGO = "vaL ogo";
  124           pr ivate stat ic final S tring VA_L OGO_RESOUR CE = "7_VA _1COLOR_HO RIZONT_12C 9F6.jpg";
  125  
  126           pr ivate stat ic final S tring CHEC KBOX ="che ckbox";
  127           pr ivate stat ic final S tring CHEC KBOX_RESOU RCE = "che ckbox.png" ;
  128  
  129           pr ivate stat ic final S tring STAT EMENT_DATE  = "Statem entDate";
  130           pr ivate stat ic final S tring PAYM ENT_DATE =  "PaymentD ate";
  131           pr ivate stat ic final S tring PAYM ENT_DUE_DA TE = "Paym entDueDate ";
  132           pr ivate stat ic final S tring PAYM ENT_DUE_ME SSAGE = "P aymentDueM essage";
  133           pr ivate stat ic final S tring PAYM ENT_DUE_ME SSAGE_TEXT  = "TO AVO ID LATE" +  HTML_LINE _BREAK +
  134                                                                                                                                 "CHAR GES PAY BA LANCE" + H TML_LINE_B REAK + "BY  ";
  135           pr ivate stat ic final S tring NO_P AYMENT_DUE _MESSAGE_T EXT = "NO  PAYMENT DU E";
  136           pr ivate stat ic final S tring BALA NCE = "Bal ance";
  137           pr ivate stat ic final S tring AMOU NT_DUE = " AmountDue" ;
  138           pr ivate stat ic final S tring PATI ENT_NAME =  "PatientN ame";
  139           pr ivate stat ic final S tring PATI ENT_ADDRES S = "Patie ntAddress" ;
  140           pr ivate stat ic final S tring PREV IOUS_BALAN CE = "Prev iousBalanc e";
  141           pr ivate stat ic final S tring NEW_ CHARGES =  "NewCharge s";
  142           pr ivate stat ic final S tring PAYM ENTS_RECEI VED = "Pay mentsRecei ved";
  143           pr ivate stat ic final S tring ACCO UNT_NUMBER _RAW = "Ac countNumbe rRaw";
  144           pr ivate stat ic final S tring ACCO UNT_NUMBER  = "Accoun tNumber";
  145           pr ivate stat ic final S tring LOCA L_MESSAGE  = "LocalMe ssage";
  146           pr ivate stat ic final S tring LOCA L_MESSAGE_ TEXT = "LO CAL VA'S M ESSAGE";
  147           pr ivate stat ic final S tring LOCA L_MESSAGE_ MULTISITE_ TEXT = HTM L_LINE_BRE AK + HTML_ NON_BREAKI NG_SPACE +  HTML_NON_ BREAKING_S PACE +
  148                                                                                                                                          "* CONS OLIDATED S TATEMENT G ENERATED"  +
  149                                                                                                                                          HTML_LI NE_BREAK +  HTML_NON_ BREAKING_S PACE + HTM L_NON_BREA KING_SPACE  +
  150                                                                                                                                          "* REVI EW TEAR-OF F COUPON F OR AMOUNT  DUE";
  151           pr ivate stat ic final S tring MAIL ING_LABEL  = "Mailing Label";
  152           pr ivate stat ic final S tring SITE _LOCATION_ NAME = "Si teLocation Name";
  153           pr ivate stat ic final S tring SITE _ADDRESS =  "SiteAddr ess";
  154           pr ivate stat ic final S tring SITE _CITY_STAT E_ZIP = "S iteCitySta teZip";
  155           pr ivate stat ic final S tring QUES TIONS_PHON E = "Quest ionsPhone" ;
  156           pr ivate stat ic final S tring PAY_ BY_PHONE =  "PayByPho ne";
  157           pr ivate stat ic final S tring PAY_ BY_PHONE_T EXT = "1-8 88-827-481 7";
  158           pr ivate stat ic final S tring PAY_ HOURS = "P ayHours";
  159           pr ivate stat ic final S tring PAY_ HOURS_TEXT  = "Mon -  Fri 8am -  8pm EST";
  160           pr ivate stat ic final S tring MAIL _TO_ADDRES S = "MailT oAddress";
  161           pr ivate stat ic final S tring MAIL _TO_ADDRES S_TEXT = " DEPARTMENT  OF VETERA NS AFFAIRS " + HTML_L INE_BREAK  +
  162                                                                                                                        "PO  BOX 53026 9" + HTML_ LINE_BREAK  +
  163                                                                                                                        "AT LANTA GA 3 0353-0269" ;
  164  
  165  
  166           //  Propertie s
  167           pr ivate CBSS tmtDAO cbs StmtDAO;
  168  
  169           pr ivate CBSS iteStmtDAO  cbsSiteSt mtDAO;
  170  
  171           pr ivate CBSS iteTransDA O cbsSiteT ransDAO;
  172  
  173   //      pr ivate Stat ionInfoUti l stationI nfoService ;
  174  
  175           pr ivate Jasp erReport m ainReport;
  176           pr ivate Jasp erReport d etailSubre port;
  177           pr ivate Jasp erReport s iteTitleSu breport;
  178           pr ivate Jasp erReport s iteTotalSu breport;
  179           pr ivate Jasp erReport s iteDelimit erSubrepor t;
  180           pr ivate Jasp erReport s iteTrailin gSpaceSubr eport;
  181           pr ivate Jasp erReport s iteFillerS paceSubrep ort;
  182           pr ivate Jasp erReport d etailEntry Subreport;
  183           pr ivate Jasp erReport s iteLateStm tSubreport ;
  184  
  185           pr ivate Imag e vaLogo;
  186           pr ivate Imag e checkbox ;
  187  
  188           pu blic CBSSt mtDAO getC bsStmtDAO( ) {
  189                    retu rn this.cb sStmtDAO;
  190           }
  191  
  192           pu blic void  setCbsStmt DAO(CBSStm tDAO inCbs StmtDAO) {
  193                    this .cbsStmtDA O = inCbsS tmtDAO;
  194           }
  195  
  196           pu blic CBSSi teStmtDAO  getCbsSite StmtDAO()  {
  197                    retu rn this.cb sSiteStmtD AO;
  198           }
  199  
  200           pu blic void  setCbsSite StmtDAO(CB SSiteStmtD AO inCbsSi teStmtDAO)  {
  201                    this .cbsSiteSt mtDAO = in CbsSiteStm tDAO;
  202           }
  203  
  204           pu blic CBSSi teTransDAO  getCbsSit eTransDAO( ) {
  205                    retu rn this.cb sSiteTrans DAO;
  206           }
  207  
  208           pu blic void  setCbsSite TransDAO(C BSSiteTran sDAO inCbs SiteTransD AO) {
  209                    this .cbsSiteTr ansDAO = i nCbsSiteTr ansDAO;
  210           }
  211  
  212   //      pu blic Stati onInfoServ ice getSta tionInfoSe rvice() {
  213   //               retu rn station InfoServic e;
  214   //      }
  215   //
  216   //      pu blic void  setStation InfoServic e(StationI nfoService  stationIn foService)  {
  217   //               this .stationIn foService  = stationI nfoService ;
  218   //      }
  219           
  220           pu blic void  initJasper Report(){
  221  
  222                    Stri ng mainRep ortJasper  = "Consoli datedPatie ntStatemen t.jrxml";
  223                    Stri ng detailS ubreportJa sper = "Cp sSiteSubre port.jrxml ";
  224                    Stri ng siteTit leSubrepor tJasper =  "CpsSiteTi tleSubrepo rt.jrxml";
  225                    Stri ng siteTot alSubrepor tJasper =  "CpsSiteTo talSubrepo rt.jrxml";
  226                    Stri ng siteDel imiterSubr eportJaspe r = "CpsSi teDelimite rSubreport .jrxml";
  227                    Stri ng siteTra ilingSpace SubreportJ asper = "C psSiteTrai lingSpaceS ubreport.j rxml";
  228                    Stri ng siteFil lerSpaceSu breportJas per = "Cps SiteFiller SpaceSubre port.jrxml ";
  229                    Stri ng detailE ntrySubrep ortJasper  = "CpsSite EntrySubre port.jrxml ";
  230                    Stri ng siteLat eStmtJaspe r = "CpsSi teLateStmt Subreport. jrxml";
  231  
  232                    try
  233                    (
  234                             InputS tream main ReportIS =  this.clas sLoader.ge tResourceA sStream(ma inReportJa sper);
  235                             InputS tream deta ilSubrepor tIS = this .classLoad er.getReso urceAsStre am(detailS ubreportJa sper);
  236                             InputS tream site TitleSubre portIS = t his.classL oader.getR esourceAsS tream(site TitleSubre portJasper );
  237                             InputS tream site TotalSubre portIS = t his.classL oader.getR esourceAsS tream(site TotalSubre portJasper );
  238                             InputS tream site DelimiterS ubreportIS  = this.cl assLoader. getResourc eAsStream( siteDelimi terSubrepo rtJasper);
  239                             InputS tream site TrailingSp aceSubrepo rtIS = thi s.classLoa der.getRes ourceAsStr eam(siteTr ailingSpac eSubreport Jasper);
  240                             InputS tream site FillerSpac eSubreport IS = this. classLoade r.getResou rceAsStrea m(siteFill erSpaceSub reportJasp er);
  241                             InputS tream deta ilEntrySub reportIS =  this.clas sLoader.ge tResourceA sStream(de tailEntryS ubreportJa sper);
  242                             InputS tream site LateStmtIS  = this.cl assLoader. getResourc eAsStream( siteLateSt mtJasper);
  243  
  244                             InputS tream vaLo goIs = thi s.classLoa der.getRes ourceAsStr eam(VA_LOG O_RESOURCE );
  245                             InputS tream chec kboxIs = t his.classL oader.getR esourceAsS tream(CHEC KBOX_RESOU RCE);
  246                    )
  247                    {
  248                             logger .info("Com piling Jas per Report s");
  249  
  250                             this.v aLogo = Im ageIO.read (vaLogoIs) ;
  251                             this.c heckbox =  ImageIO.re ad(checkbo xIs);
  252                             
  253                             // Com pile the m ain report  file to a n object t o populate
  254                             // dyn amically.
  255                             this.m ainReport  = JasperCo mpileManag er.compile Report(mai nReportIS) ;
  256                             this.d etailSubre port = Jas perCompile Manager.co mpileRepor t(detailSu breportIS) ;
  257                             this.s iteTitleSu breport =  JasperComp ileManager .compileRe port(siteT itleSubrep ortIS);
  258                             this.s iteTotalSu breport =  JasperComp ileManager .compileRe port(siteT otalSubrep ortIS);
  259                             this.s iteDelimit erSubrepor t = Jasper CompileMan ager.compi leReport(s iteDelimit erSubrepor tIS);
  260                             this.s iteTrailin gSpaceSubr eport = Ja sperCompil eManager.c ompileRepo rt(siteTra ilingSpace SubreportI S);
  261                             this.s iteFillerS paceSubrep ort = Jasp erCompileM anager.com pileReport (siteFille rSpaceSubr eportIS);
  262                             this.d etailEntry Subreport  = JasperCo mpileManag er.compile Report(det ailEntrySu breportIS) ;
  263                             this.s iteLateStm tSubreport  = JasperC ompileMana ger.compil eReport(si teLateStmt IS);
  264  
  265                    } ca tch (Numbe rFormatExc eption e)  {
  266                             // Sca n Line may  throw thi s.
  267                             logger .error("Nu mber Forma t Exceptio n: " + e.g etMessage( ));
  268  
  269                    } ca tch (JRExc eption e)  {
  270                             // Jas per may th row this.
  271                             logger .error("JR  Exception : " + e.ge tMessage() );
  272  
  273                    } ca tch (IOExc eption e)  {
  274                             logger .error(e.g etMessage( ));
  275                    }
  276           }
  277  
  278           /* *
  279            *  Generate  a PDF stat ement for  the specif ied CBSStm t ID
  280            *  
  281            *  @param cb sStmtId
  282            *              The CBSS tmt ID.
  283            *  @return p df
  284            *                         The gene rated pdf  as a byte  array
  285            * /
  286           pu blic byte[ ] generate StatementP dfStream(f inal long  cbsStmtId)  {
  287  
  288                    Jasp erPrint ja sperPrint  = generate StatementP dfPrint(cb sStmtId);
  289                    byte  [] pdf=nu ll;
  290                    if ( jasperPrin t != null)  {
  291                             // Exp ort the dy namically  filled rep ort to dis k.
  292                             try {
  293                                      // Expor t the dyna mically fi lled repor t to strea m.
  294                                      pdf = Ja sperExport Manager.ex portReport ToPdf(jasp erPrint);
  295                             } catc h (JRExcep tion e) {
  296                                      logger.e rror(e.get Message()) ;
  297                             }
  298                    } el se {
  299                             logger .error("ja sperPrint  is null");
  300                    }
  301                    retu rn pdf;
  302           }
  303  
  304           /* *
  305            *  Generate  a PDF stat ement for  the specif ied CBSStm t ID outpu t on the
  306            *  provided  stream.
  307            *  
  308            *  @param cb sStmtId
  309            *              The CBSS tmt ID.
  310            *  @param ou tputFile
  311            *              The file name for w hich to ou tput the P DF.
  312            * /
  313           pu blic void  generateSt atementPdf File(final  long cbsS tmtId, fin al String  outputFile ) {
  314  
  315                    Jasp erPrint ja sperPrint  = generate StatementP dfPrint(cb sStmtId);
  316  
  317                    if ( jasperPrin t != null)  {
  318                             logger .info("AFT ER Generat ion: " + o utputFile) ;
  319  
  320                             // Exp ort the dy namically  filled rep ort to dis k.
  321                             try {
  322  
  323                                      JasperEx portManage r.exportRe portToPdfF ile(jasper Print, out putFile);
  324                             } catc h (JRExcep tion e) {
  325                                      logger.e rror(e.get Message()) ;
  326                             }
  327                    } el se {
  328                             logger .error("Cb s Stmt ID  not found:  " + cbsSt mtId);
  329                    }
  330           }
  331  
  332           /* *
  333            *  Generate  a Jasper P rint objec t for the  specified  CBSStmt ID .
  334            *  
  335            *  @param cb sStmtId
  336            *              The CBSS tmt ID.
  337            *  @return T he Jasper  Print obje ct.
  338            * /
  339           pu blic Jaspe rPrint gen erateState mentPdfPri nt(final l ong cbsStm tId) {
  340  
  341                    try  {
  342  
  343                             // Con vert from  CBSStmt
  344                             final  SendCBSWri tePSRecord Source psR ecordSourc e = buildR ecordSourc e(cbsStmtI d);
  345                             final  PdfConsoli datedState mentDataBe an dataBea n = buildS tatementDa taBean(psR ecordSourc e, cbsStmt Id);
  346                             
  347                             // TOD O, if abov e are null  or empty  then retur n null!?!?
  348                             
  349                             // Fix  for Defec t 630398
  350                             // - R emove faci lity total  for singl e site (he nce the de limiter li nes)
  351                             // Yip ing Yao -  01/19/2018
  352                             boolea n isMultiS ite = psRe cordSource .isMultisi teflag();
  353  
  354                             // Get  reference s.
  355                             Map<St ring, Obje ct> mainRe portValueP arametersM  = dataBea n.getMainR eportValue Parameters M();
  356                             List<P dfSiteStat ementColle ctionBean>  siteState mentCollec tionBeanL  = dataBean
  357                                               .getPdfSit eStatement Collection BeanL();
  358  
  359                             // Cre ate a data  source to  use as in puts to po pulate the  site
  360                             // sta tement sub  report po rtion of t he PDF.
  361                             JRBean Collection DataSource  siteState mentCollec tionDataSo urce = new  JRBeanCol lectionDat aSource(
  362                                               siteStatem entCollect ionBeanL);
  363                                                       
  364                             // Cre ate a para meter map  to use as  inputs to  populate t he global
  365                             // por tion of th e PDF.
  366  
  367                             // Add  the subre ports as p arameters.
  368                             mainRe portValueP arametersM .put("Cons olidatedPa tientState mentSiteSu breportPar ameter",
  369                                                                                                   th is.detailS ubreport);
  370                             mainRe portValueP arametersM .put("Cons olidatedPa tientState mentSiteTi tleSubrepo rtParamete r",
  371                                                                                                   th is.siteTit leSubrepor t);
  372                             mainRe portValueP arametersM .put("Cons olidatedPa tientState mentSiteTo talSubrepo rtParamete r",
  373                                                                                                   th is.siteTot alSubrepor t);
  374  
  375                             // Fix  for Defec t 630398
  376                             // - R emove faci lity total  for singl e site (he nce the de limiter li nes)
  377                             // Yip ing Yao -  01/19/2018
  378                             if (is MultiSite)
  379                             {        
  380                                      mainRepo rtValuePar ametersM.p ut("Consol idatedPati entStateme ntSiteDeli miterSubre portParame ter",
  381                                                                                                            this .siteDelim iterSubrep ort);
  382                             }
  383  
  384                             mainRe portValueP arametersM .put("Cons olidatedPa tientState mentSiteTr ailingSpac eSubreport Parameter"
  385                                                                                                   th is.siteTra ilingSpace Subreport) ;
  386                             mainRe portValueP arametersM .put("Cons olidatedPa tientState mentSiteFi llerSpaceS ubreportPa rameter",
  387                                                                                                   th is.siteFil lerSpaceSu breport);
  388                             mainRe portValueP arametersM .put("Cons olidatedPa tientState mentSiteEn trySubrepo rtParamete r",
  389                                                                                                   th is.detailE ntrySubrep ort);
  390                             mainRe portValueP arametersM .put("Cons olidatedPa tientState mentSiteLa teStmtSubr eportParam eter",
  391                                                                                                   th is.siteLat eStmtSubre port);
  392  
  393                             mainRe portValueP arametersM .put(VA_LO GO, this.v aLogo);
  394                             mainRe portValueP arametersM .put(CHECK BOX, this. checkbox);
  395                             
  396                             // Dyn amically f ill the re port with  the parame ter map an d sub repo rt
  397                             // col lection da ta source.
  398                             Jasper Print jasp erPrint =  JasperFill Manager.fi llReport(t his.mainRe port, main ReportValu eParameter sM,
  399                                               siteStatem entCollect ionDataSou rce);
  400  
  401                             return  jasperPri nt;
  402  
  403                    } ca tch (Numbe rFormatExc eption e)  {
  404  
  405                             // Sca n Line may  throw thi s.
  406                             logger .error(e.g etMessage( ));
  407  
  408                    } ca tch (JRExc eption e)  {
  409  
  410                             // Jas per may th row this.
  411                             logger .error(e.g etMessage( ));
  412  
  413                    } ca tch (Index OutOfBound sException  e) {
  414  
  415                             // Sca n Line may  throw thi s.
  416                             logger .error(e.g etMessage( ));
  417                    }
  418  
  419                    retu rn null;
  420           }
  421  
  422           /* *
  423            *  Build a S endCBSWrit ePSRecordS ource obje ct for the  specified  CBSStmt.  The
  424            *  returned  object is  used to po pulate a J asper Data  Source.
  425            *  
  426            *  @param cb sStmtId
  427            *              The CBSS tmt ID.
  428            *  @return T he SendCBS WritePSRec ordSource.
  429            * /
  430           pr ivate Send CBSWritePS RecordSour ce buildRe cordSource (final lon g cbsStmtI d) {
  431  
  432                    fina l SendCBSW ritePSReco rdSource p sRecordSou rce = new  SendCBSWri tePSRecord Source();
  433  
  434                    fina l SendCBSR untimeStat eImpl runt imeState =  new SendC BSRuntimeS tateImpl() ;
  435           ps RecordSour ce.setSend CBSRuntime State(runt imeState);
  436  
  437           fi nal CBSStm t cbsStmt  = this.cbs StmtDAO.ge t(cbsStmtI d);
  438  
  439           fi nal List<C BSSiteStmt > siteStmt L = this.c bsSiteStmt DAO.getAll ByCBSStmtI D(cbsStmtI d, true);
  440  
  441           fi nal List<C BSSiteTran s> siteTra nsL = this .cbsSiteTr ansDAO.get AllByCBSSi teStmtID(c bsStmtId);
  442           if (siteStmtL .size() >  1) psRecor dSource.se tMultisite flag(true) ;
  443  
  444           fo r(CBSSiteS tmt siteSt mt : siteS tmtL) {
  445               siteStmt. setSiteTra nsL(new Ar rayList<CB SSiteTrans >());
  446           }
  447  
  448           fo r(CBSSiteT rans trans  : siteTra nsL){
  449               for(CBSSi teStmt sit eStmt : si teStmtL) {
  450                       i f(trans.ge tSiteStmtI d() == sit eStmt.getI d()){
  451                                sit eStmt.getS iteTransL( ).add(tran s);
  452                       }
  453               }
  454           }
  455  
  456           cb sStmt.setS iteStmtL(s iteStmtL);
  457  
  458           fi nal List<P SSite> psS itesList =  runtimeSt ate.getPSS itesList() ;
  459           ps SitesList. add(create PSSite(PSR ecord.Data Type.PH, 1 , 1, siteS tmtL.get(0 ), 1, cbsS tmt.getNew Balance(). getDouble( )));
  460  
  461           fi nal List<C BSStmt> cb sStmtL2 =  new ArrayL ist<>(1);
  462           cb sStmtL2.ad d(cbsStmt) ;
  463  
  464           fi nal Map<St ring, List <CBSStmt>>  cbsListsB ySite = ru ntimeState .getCBSLis tsBySite() ;
  465           cb sListsBySi te.put(cbs Stmt.getPr imarySiteS tmt().getS tationNum( ), cbsStmt L2);
  466  
  467           ps RecordSour ce.setPsSi tesList(ps SitesList) ;
  468           ps RecordSour ce.setCbsL istsBySite (cbsListsB ySite);
  469  
  470           re turn psRec ordSource;
  471           }
  472  
  473           /* *
  474            *  Build a P SSite obje ct from da ta retriev ed from th e database .
  475            *  
  476            *  @param st atementTyp e
  477            *  @param ps SeqNum
  478            *  @param ps TotSeqNum
  479            *  @param pr imarySite
  480            *  @param ps TotStateme nt
  481            *  @param ps StatementV al
  482            *  @return T he PSSite  object.
  483            * /
  484           pr ivate PSSi te createP SSite(fina l PSRecord .DataType  statementT ype, final  int psSeq Num, final  int psTot SeqNum,
  485                             final  CBSSiteStm t primaryS ite, final  int psTot Statement,  final dou ble psStat ementVal)  {
  486                    PSSi te psSite  = new PSSi te();
  487                    psSi te.setType (PSRecord. DataType.P S);
  488                    psSi te.setStat ementType( statementT ype);
  489  
  490                    psSi te.setSeqN um(psSeqNu m);
  491                    psSi te.setTotS eqNum(psTo tSeqNum);
  492                    psSi te.setFaci lityNum(pr imarySite. getStation Num());
  493                    psSi te.setFaci lityPhoneN um(primary Site.getSt ationPhone Num());
  494                    psSi te.setStat ementDate( primarySit e.getState mentDate() );
  495                    psSi te.setProc essDate(pr imarySite. getProcess Date());
  496                    psSi te.setTotS tatement(p sTotStatem ent);
  497                    psSi te.setStat ementVal(n ew Money(p sStatement Val, 11));
  498  
  499                    retu rn psSite;
  500           }
  501  
  502           /* *
  503            *  Create a  PdfConsoli datedState mentDataBe an of para meters to  populate t he
  504            *  PDF repor t from a S endCBSWrit ePSRecordS ource obje ct.
  505            *  
  506            *  @param ps RecordSour ce
  507            *              The Send CBSWritePS RecordSour ce object  containing  the reque sted
  508            *              CBSStmt  data.
  509            *  @param cb sStmtId 
  510            *  @return T he PdfCons olidatedSt atementDat aBean for  the Jasper  Report.
  511            * /
  512           pr ivate PdfC onsolidate dStatement DataBean b uildStatem entDataBea n(final Se ndCBSWrite PSRecordSo urce psRec ordSource,  long cbsS tmtId) {
  513  
  514                    bool ean valid  = true;
  515                    bool ean multis iteflag =  psRecordSo urce.isMul tisiteflag ();
  516  
  517                    // B uild the r eport valu e map.
  518                    Map< String, Ob ject> main ReportValu eParameter sM = new H ashMap<>() ;
  519  
  520                    // D eclare the  report da ta source.
  521                    List <PdfSiteSt atementCol lectionBea n> siteSta tementColl ectionBean L;
  522  
  523                    // S ite statem ent Map<PS SiteStmt,  List<PSDet ails>>
  524                    Map< PSSiteStmt , List<PSD etails>> s iteStateme ntM = new  LinkedHash Map<>();
  525  
  526                    // P S
  527                    Stri ng facilit yNum = EMP TY_STRING;
  528                    PSRe cord psRec ord = psRe cordSource .nextPSRec ord(true);
  529                    PSSi teStmt pv  = null;
  530                    whil e (psRecor d != null)  {
  531                             if (ps Record ins tanceof PS Site) {
  532                                      logger.i nfo("PS");
  533                                      facility Num = ((PS Site) psRe cord).getF acilityNum ();
  534                                      appendPS Map(mainRe portValueP arametersM , (PSSite)  psRecord,  multisite flag);
  535                             } else  if (psRec ord instan ceof PSPat ient) {
  536                                      logger.i nfo("PH");
  537                                      appendPH Map(mainRe portValueP arametersM , (PSPatie nt) psReco rd, multis iteflag);
  538                                      appendSc anLine(mai nReportVal ueParamete rsM, facil ityNum);
  539                             } else  if (psRec ord instan ceof PSSit eStmt) {
  540                                      logger.i nfo("PV");
  541                                      pv = (PS SiteStmt)  psRecord;
  542                                      List<PSD etails> si teDetailL  = new Arra yList<>();
  543                                      siteStat ementM.put (pv, siteD etailL);
  544                             } else  if (psRec ord instan ceof PSDet ails) {
  545                                      logger.i nfo("PD");
  546                                      siteStat ementM.get (pv).add(( PSDetails)  psRecord) ;
  547                             } else  {
  548                                      valid =  false;
  549                                      logger.e rror("Unkn own Record  Type");
  550                             }
  551  
  552                             if (va lid) {
  553                                      psRecord  = psRecor dSource.ne xtPSRecord (true);
  554                             } else  {
  555                                      break;
  556                             }
  557                    }
  558  
  559                    // T ODO, If no t valid lo g error?
  560                    if ( valid) {
  561                             siteSt atementCol lectionBea nL = build SiteStatem entCollect ionBean(si teStatemen tM, cbsStm tId, multi siteflag);
  562  
  563                             popula tePseudoSt aticData(m ainReportV alueParame tersM, fac ilityNum);
  564  
  565                             return  new PdfCo nsolidated StatementD ataBean(ma inReportVa lueParamet ersM, site StatementC ollectionB eanL);
  566                    }
  567  
  568                    // T ODO, ensur e whatever  calls thi s doesn't  crash with  null.
  569                    retu rn null;
  570           }
  571  
  572           /* *
  573            *  Populate  parameter  value map  for the PD F with PSS ite attrib utes.
  574            *  
  575            *  @param re portValueM
  576            *              The para meter map  to populat e.
  577            *  @param si te
  578            *              The PSSi te object  containing  the data  for the si te.
  579            * /
  580           pr ivate void  appendPSM ap(Map<Str ing, Objec t> reportV alueM, fin al PSSite  site, bool ean multis iteflag) {
  581  
  582                    fina l Date sta tementDate  = site.ge tStatement Date();
  583                    fina l SimpleDa teFormat s tatementDa teFormat =  new Simpl eDateForma t(REPORT_D ATE_FORMAT );
  584                    repo rtValueM.p ut(STATEME NT_DATE, s tatementDa teFormat.f ormat(stat ementDate) );
  585  
  586                    // T he balance  determine s payment  date.
  587                    fina l double b alance = s ite.getSta tementVal( ).getDoubl e();
  588  
  589                    // T ODO, When  is this?
  590                    fina l Date pro cessDate =  site.getP rocessDate ();
  591                    fina l SimpleDa teFormat p rocessDate Format = n ew SimpleD ateFormat( REPORT_DAT E_FORMAT);
  592                    repo rtValueM.p ut(PAYMENT _DATE, pro cessDateFo rmat.forma t(processD ate));
  593  
  594                    // B uild the p ayment par ameters.
  595                    if ( balance >  0) {
  596  
  597                             // Pay ment Due D ate is the  statement Date plus  FULL_PAYME NT_DAY_NUM BER_DELTA.
  598                             // TOD O, test th is with ro ll-over fr om Decembe r to Janua ry.
  599                             final  SimpleDate Format pay mentDueDat eFormat =  new Simple DateFormat (REPORT_DA TE_FORMAT) ;
  600                             Calend ar c = Cal endar.getI nstance();
  601                             c.setT ime(statem entDate);
  602                             c.add( Calendar.D ATE, FULL_ PAYMENT_DA Y_NUMBER_D ELTA);
  603                             final  Date payme ntDueDate  = c.getTim e();
  604                             //Adde d 8/29
  605                             
  606                             report ValueM.put (PAYMENT_D UE_DATE, p aymentDueD ateFormat. format(pay mentDueDat e));
  607                             //adde d 11/29 fo r single o r multiple  site
  608                             if(mul tisiteflag ){
  609                                      reportVa lueM.put(P AYMENT_DUE _MESSAGE,  STRING_SPA CE);
  610                                      reportVa lueM.put(B ALANCE, ST RING_SPACE );
  611  
  612                             }else{
  613                             report ValueM.put (PAYMENT_D UE_MESSAGE , PAYMENT_ DUE_MESSAG E_TEXT
  614                                               + paymentD ueDateForm at.format( paymentDue Date));
  615                             
  616                             report ValueM.put (BALANCE,  site.getSt atementVal ().getDoub leAsAbsolu teString() );
  617                             
  618                             }
  619                             report ValueM.put (AMOUNT_DU E, site.ge tStatement Val().getD oubleAsAbs oluteStrin g());
  620  
  621                    } el se {
  622  
  623                             final  String pay mentDueDat e = NO_PAY MENT_DUE_M ESSAGE_TEX T;
  624                             report ValueM.put (PAYMENT_D UE_DATE, p aymentDueD ate);
  625                             //Adde d 8/25/201 7
  626                             if(mul tisiteflag ){
  627                             report ValueM.put (PAYMENT_D UE_MESSAGE , STRING_S PACE);
  628                             report ValueM.put (BALANCE,  STRING_SPA CE);
  629                             }else{
  630                                      reportVa lueM.put(P AYMENT_DUE _MESSAGE,  paymentDue Date);
  631                                      reportVa lueM.put(B ALANCE, id entifyValu eAsCredit( site.getSt atementVal ().getDoub leAsAbsolu teString() ));
  632                             }
  633                             report ValueM.put (AMOUNT_DU E, Money.D OUBLE_STRI NG_FORMAT) ;
  634                    }
  635           }
  636  
  637           /* *
  638            *  Populate  parameter  value map  for the PD F with PSP atient att ributes.
  639            *  
  640            *  @param re portValueM
  641            *              The para meter map  to populat e.
  642            *  @param pa tient
  643            *              The PSPa tient obje ct contain ing the da ta for the  site.
  644            * /
  645           pr ivate void  appendPHM ap(Map<Str ing, Objec t> reportV alueM, fin al PSPatie nt patient ,boolean m ultisitefl ag) {
  646  
  647                    // B uild the p atient nam e and whil e doing so  do not in clude any  empty or
  648                    // n ull names.
  649                    Stri ngBuilder  patientNam e = new St ringBuilde r();
  650                    if ( (patient.g etPatientF irstName()  != null)  && !patien t.getPatie ntFirstNam e().trim() .isEmpty() ) {
  651                             patien tName.appe nd(patient .getPatien tFirstName ().trim()) ;
  652                    }
  653                    if ( (patient.g etPatientM iddleName( ) != null)  && !patie nt.getPati entMiddleN ame().trim ().isEmpty ()) {
  654                             patien tName.appe nd(STRING_ SPACE);
  655                             patien tName.appe nd(patient .getPatien tMiddleNam e().trim() );
  656                    }
  657                    if ( (patient.g etPatientL astName()  != null) & & !patient .getPatien tLastName( ).trim().i sEmpty())  {
  658                             patien tName.appe nd(STRING_ SPACE);
  659                             patien tName.appe nd(patient .getPatien tLastName( ).trim());
  660                    }
  661                    repo rtValueM.p ut(PATIENT _NAME, pat ientName.t oString()) ;
  662  
  663                    // T his is the  patient a ddress in  the title  and coupon  band.
  664                    Stri ngBuilder  address =  new String Builder();
  665                    if ( (patient.g etAddress1 () != null ) && !pati ent.getAdd ress1().is Empty()) {
  666                             addres s.append(p atient.get Address1() );
  667                    }
  668                    if ( (patient.g etAddress2 () != null ) && !pati ent.getAdd ress2().is Empty()) {
  669                             addres s.append(H TML_LINE_B REAK);
  670                             addres s.append(p atient.get Address2() );
  671                    }
  672                    if ( (patient.g etAddress3 () != null ) && !pati ent.getAdd ress3().is Empty()) {
  673                             addres s.append(H TML_LINE_B REAK);
  674                             addres s.append(p atient.get Address3() );
  675                    }
  676                    fina l String p atientCity StateZip =  patient.g etCity() +  STRING_SP ACE + pati ent.getSta te() + STR ING_SPACE  + patient. getZipCode ();
  677                    addr ess.append (HTML_LINE _BREAK);
  678                    addr ess.append (patientCi tyStateZip );
  679                    repo rtValueM.p ut(PATIENT _ADDRESS,  address.to String());
  680  
  681                    // B uild the p ayment par ameters.
  682                    if ( patient.ge tPrevBalan ce().getDo uble() > 0 ) {
  683                             report ValueM.put (PREVIOUS_ BALANCE, p atient.get PrevBalanc e().getDou bleAsAbsol uteString( ));
  684                    } el se {
  685                             report ValueM.put (PREVIOUS_ BALANCE, i dentifyVal ueAsCredit (patient.g etPrevBala nce().getD oubleAsAbs oluteStrin g()));
  686                    }
  687                    repo rtValueM.p ut(NEW_CHA RGES, pati ent.getTot alCharges( ).getDoubl eAsAbsolut eString()) ;
  688                    repo rtValueM.p ut(PAYMENT S_RECEIVED , patient. getTotalCr edits().ge tDoubleWit hSignSuffi xAsString( ));
  689  
  690                    // F ix for Def ect 616442
  691                    // -  Reformat  Account Nu mber
  692                    // Y iping Yao  - 01/30/20 18
  693                    Stri ng account NumberDisp  = buildAc countNumbe rDisp(pati ent);
  694  
  695                    // S ave the ra w account  number for  later use  by the Sc an Line.
  696                    // T he formate d account  number is  the one us ed in the  actual for m.
  697                    repo rtValueM.p ut(ACCOUNT _NUMBER_RA W, account NumberDisp );
  698                    repo rtValueM.p ut(ACCOUNT _NUMBER, f ormatAccou ntNumber(a ccountNumb erDisp));
  699                    //re portValueM .put("Acco untNumberR aw", patie nt.getAcnt NumDisp(). trim());
  700                    //re portValueM .put("Acco untNumber" , formatAc countNumbe r(patient. getAcntNum Disp().tri m()));
  701  
  702                    // T ODO, Figur e out if t his is lat e statemen t message  or special  notes
  703                    // o r both?
  704                    // A DDED 8/25/ 2017
  705                    Stri ngBuilder  localMessa ge = new S tringBuild er();
  706  
  707                    loca lMessage.a ppend(HTML _NON_BREAK ING_SPACE) ;
  708                    loca lMessage.a ppend(LOCA L_MESSAGE_ TEXT);
  709  
  710                    if(m ultisitefl ag){
  711                             localM essage.app end(LOCAL_ MESSAGE_MU LTISITE_TE XT);
  712                    }
  713  
  714                    repo rtValueM.p ut(LOCAL_M ESSAGE, lo calMessage .toString( ));
  715           }
  716  
  717           /* *
  718            *  Create a  scan line  and append  to the pa rameter ma p.
  719            *  
  720            *  @param re portValueM
  721            *              The para meter map  to populat e.
  722            *  @param fa cilityNum
  723            *              The prim ary site/f acility fo r the repo rt.
  724            * /
  725           pr ivate void  appendSca nLine(Map< String, Ob ject> repo rtValueM,  final Stri ng facilit yNum) {
  726  
  727                    fina l String a ccountNumb er = (Stri ng) report ValueM.get (ACCOUNT_N UMBER_RAW) ;
  728                    fina l String a mountDue =  (String)  reportValu eM.get(AMO UNT_DUE);
  729  
  730                    fina l ScanLine  scanLine  = new Scan Line(facil ityNum, ac countNumbe r, amountD ue);
  731  
  732                    // A ppend thes e values.
  733                    repo rtValueM.p ut(MAILING _LABEL, sc anLine.get Calculated ScanLine() );
  734           }
  735  
  736           /* *
  737            *  Populate  pseudo sta tic data i n the para meter map.
  738            *  
  739            *  @param re portValueM
  740            *              The para meter map  to populat e.
  741            *  @param fa cilityNum
  742            *              The prim ary site f or which t o use as l ookup key  for the ps eudo
  743            *              static d ata.
  744            * /
  745           pr ivate void  populateP seudoStati cData(Map< String, Ob ject> repo rtValueM,  final Stri ng facilit yNum) {
  746  
  747                    Stat ionInfo st ation = St ationInfoU til.getSta tion(facil ityNum);
  748                    repo rtValueM.p ut(SITE_LO CATION_NAM E, station .getFacili tyDesc());
  749  
  750                    // T his is the  address a t the top  of the rep ort header  and is th e VAMC's a ddress.
  751                    Addr ess statio nAddress =  station.g etAddress( );
  752                    Stri ngBuilder  address =  new String Builder();
  753                    if ( (stationAd dress.getA ddress1()  != null) & & !station Address.ge tAddress1( ).isEmpty( )) {
  754                             addres s.append(s tationAddr ess.getAdd ress1());
  755                    }
  756                    if ( (stationAd dress.getA ddress2()  != null) & & !station Address.ge tAddress2( ).isEmpty( )) {
  757                             addres s.append(H TML_LINE_B REAK);
  758                             addres s.append(s tationAddr ess.getAdd ress2());
  759                    }
  760                    if ( (stationAd dress.getA ddress3()  != null) & & !station Address.ge tAddress3( ).isEmpty( )) {
  761                             addres s.append(H TML_LINE_B REAK);
  762                             addres s.append(s tationAddr ess.getAdd ress3());
  763                    }
  764  
  765                    // T his is wro ng, and st ation.getZ ipCode() r eturns a Z ipCode obj ect, not a ctual ZIP  code in st ring forma t.
  766                    // A nd it is n ot needed,  since the  SITE_CITY _STATE_ZIP  already s upplies th e Cite, St ate and ZI P Code.
  767                    // T his was no t shown si nce HTML o nly has on e line for  the addre ss.
  768                    // Y iping Yao  - 02/21/20 18
  769                    //fi nal String  siteCityS tateZip =  station.ge tCity() +  STRING_SPA CE + stati on.getStat e() + STRI NG_SPACE +  station.g etZipCode( );
  770                    //ad dress.appe nd(HTML_LI NE_BREAK);
  771                    //ad dress.appe nd(siteCit yStateZip) ;
  772  
  773                    repo rtValueM.p ut(SITE_AD DRESS, add ress.toStr ing());
  774  
  775                    // F ix for Def ect 680703
  776                    // -  Format ZI P Code as:  #####-### #
  777                    // Y iping Yao  - 02/21/20 18
  778                    fina l String p lus4Code =  ( station .getZipCod e().getZip Code2() ==  null ||
  779                                                                            sta tion.getZi pCode().ge tZipCode2( ).trim().i sEmpty() | |
  780                                                                            sta tion.getZi pCode().ge tZipCode2( ).equals(" 0000") ) ?
  781                                                                            EMP TY_STRING  : STRING_D ASH + stat ion.getZip Code().get ZipCode2() ;
  782                    repo rtValueM.p ut(SITE_CI TY_STATE_Z IP,
  783                                                        S tring.form at("%s, %s  %s", stat ion.getCit y(), stati on.getStat e(),
  784                                                                                     stati on.getZipC ode().getZ ipCode1()  + plus4Cod e));
  785                    //re portValueM .put(SITE_ CITY_STATE _ZIP,
  786                    //                String.f ormat("%s,  %s %s", s tation.get City(), st ation.getS tate(), st ation.getZ ipCode().g etZipCode1 ()));
  787  
  788                    // T his is the  phone num ber of the  HRC Call  Center (pe r VISN).
  789                    repo rtValueM.p ut(QUESTIO NS_PHONE,  station.ge tTelephone Num1());
  790  
  791                    // F or some re ason this  is hard co ded on the  form.
  792                    // S o it is ha rd coded h ere for ea sier updat e.
  793                    repo rtValueM.p ut(PAY_BY_ PHONE, PAY _BY_PHONE_ TEXT);
  794                    repo rtValueM.p ut(PAY_HOU RS, PAY_HO URS_TEXT);
  795                    
  796                    // M AIL TO: ma iling addr ess.
  797                    // O ne address  per CPAC.
  798                    // T ODO, chang e this to  html field  type and  concatenat e a single  field.
  799                    repo rtValueM.p ut(MAIL_TO _ADDRESS,  MAIL_TO_AD DRESS_TEXT );
  800           }
  801  
  802           /* *
  803            *  Build a P dfSiteStat ementColle ctionBean  from the s ite statem ent map to  be
  804            *  used as a  Jasper da ta source.
  805            *  
  806            *  @param si teStatemen tM
  807            *              The site  statement  map.
  808            *  @param cb sStmtId
  809            *  @param is MultiSite  - the mult i-site fla g
  810            *  @return L ist of Pdf SiteStatem entCollect ionBean. N ote that t he list is
  811            *          s ize of one  because t he Jasper  data sourc e that is  constructe d
  812            *          r equires a  list.
  813            * /
  814           pr ivate List <PdfSiteSt atementCol lectionBea n> buildSi teStatemen tCollectio nBean(
  815                             Map<PS SiteStmt,  List<PSDet ails>> sit eStatement M, long cb sStmtId, b oolean isM ultiSite)  {
  816  
  817                    PdfS iteStateme ntCollecti onBean sit eStatement Collection  = new Pdf SiteStatem entCollect ionBean();
  818  
  819                    List <PdfSiteSt atementBea n> siteSta tementBean L = new Ar rayList<>( );
  820  
  821                    for  (Map.Entry <PSSiteStm t, List<PS Details>>  siteEntry  : siteStat ementM.ent rySet()) {
  822  
  823                             PdfSit eStatement Bean site  = new PdfS iteStateme ntBean();
  824  
  825                             // Fix  for Defec t 669283
  826                             // - R emove Faci lity Title  for singl e site
  827                             // Yip ing Yao -  02/01/2018
  828                             if (is MultiSite)
  829                             {
  830                                      final St ring facil ityTitle =  StationIn foUtil.get Station(si teEntry.ge tKey().get FacilityNu m()).getFa cilityDesc ();
  831  
  832                                      // Fix f or Defect  661784
  833                                      // - Rem ove # Faci lity Numbe r
  834                                      // Yipin g Yao - 01 /22/2018
  835                                      site.set Facility(f acilityTit le);
  836                                      //site.s etFacility (facilityT itle + " #  " + siteE ntry.getKe y().getFac ilityNum() );
  837                             }
  838  
  839                             //set  late state ment flag  for site i f statemen t is marke d late
  840                             final  CBSStmt cb sStmt = th is.cbsStmt DAO.get(cb sStmtId);
  841  
  842                             if(cbs Stmt.getLa teStmtMsg( )){
  843                                      site.set LateStmtFl ag(Boolean .TRUE);
  844                             }
  845  
  846                             List<P dfSiteStat ementEntry Bean> pdfS iteStateme ntEntryBea nL = new A rrayList<> ();
  847  
  848                             boolea n isAdding Space = fa lse;
  849  
  850                             for (P SDetails d etails : s iteEntry.g etValue())  {
  851                                      // TODO,  split the  detail in to multipl e lines.
  852                                      // 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.
  853                                      // TODO,  check tra ns desc an d wrap wit h [] for s uspended c harges
  854  
  855                                      // Fix f or Defect  630421
  856                                      // - Not  display " 0.00" in a mount
  857                                      // Yipin g Yao - 01 /11/2018
  858                                      String t ransAmount  = details .getTransA mount().ge tDoubleWit hSignSuffi xAsString( );
  859  
  860                                      transAmo unt = (tra nsAmount.e quals(Mone y.DOUBLE_S TRING_FORM AT)) ? STR ING_SPACE  : transAmo unt;
  861  
  862                                      // Fix f or Defect  661797
  863                                      // - lin e up decim als in amo unt column
  864                                      //   Add  space to  positive n umber (wit hout the m inus sign  "-"),
  865                                      //   so  that the c ents are l ine up cor rectly.
  866                                      // Yipin g Yao - 01 /22/2018
  867  
  868                                      if (tran sAmount.le ngth() > 1  && transA mount.char At(transAm ount.lengt h() - 1) ! = '-')
  869                                      {
  870                                               isAddingSp ace = true ;
  871                                               transAmoun t += HTML_ NON_BREAKI NG_SPACE;
  872                                      }
  873  
  874                                      PdfSiteS tatementEn tryBean de tailEntry  = new PdfS iteStateme ntEntryBea n(formatDe tailDescri ption(deta ils.getTra nsDesc(),  details.ge tDatePoste d()),
  875                                                       tr ansAmount,  details.g etReferenc eNum());
  876                                      pdfSiteS tatementEn tryBeanL.a dd(detailE ntry);
  877                             }
  878  
  879                             site.s etRecords( pdfSiteSta tementEntr yBeanL);
  880  
  881                             // Fix  for Defec ts 630437  and 630398
  882                             // - A dd text to  facility  total labe l for mult i-site
  883                             // - R emove faci lity total  for singl e site
  884                             // Yip ing Yao -  01/18/2018
  885                             //site .setTotalL abel("FACI LITY #" +  siteEntry. getKey().g etFacility Num() + "  TOTAL");
  886                             if (is MultiSite)
  887                             {
  888                                      site.set TotalLabel ("PREVIOUS  AND CURRE NT CHARGES  FOR FACIL ITY #" + s iteEntry.g etKey().ge tFacilityN um() + " T OTAL");
  889  
  890                                      // Fix f or Defect  661797
  891                                      // - lin e up decim als in tot al column  as well
  892                                      //   Add  space to  total if t here is ne gative amo unt,
  893                                      //   so  that the c ents are l ine up cor rectly.
  894                                      // Yipin g Yao - 01 /22/2018
  895                                      String s iteTotal =  siteEntry .getKey(). getStation TotalAmoun t().getDou bleAsStrin g();
  896  
  897                                      if (isAd dingSpace)
  898                                      {
  899                                               siteTotal  += HTML_NO N_BREAKING _SPACE;
  900                                      }
  901  
  902                                      site.set Total(site Total);
  903                             }
  904  
  905                             siteSt atementBea nL.add(sit e);
  906                    }
  907  
  908                    site StatementC ollection. setSiteSta tementL(si teStatemen tBeanL);
  909  
  910                    // F ix for Def ect 711459
  911                    // -  This may  fix the mi ssing deta ils line o n the seco nd page by  subtract  1.
  912                    // Y iping Yao  - 04/04/20 18
  913                    // S plit the s ite statem ent collec tion bean.
  914                    site StatementC ollection. split(MAX_ LENGTH_FIR ST_PAGE -  1);
  915  
  916                    // A dd filler  space to e xtend box  to footer  of page
  917                    site StatementC ollection. addFillerS pace(MAX_L ENGTH_FIRS T_PAGE, MA X_LENGTH_E XTENSION_P AGE);
  918  
  919                    retu rn Arrays. asList(sit eStatement Collection );
  920           }
  921  
  922           /* *
  923            *  Format th e descript ion text a s shown on  the examp les
  924            *  provided  by AITC.
  925            *  
  926            *  @param de tailDesc
  927            *              ----The  original d escription  text.
  928            *  @return T he formatt ed descrip tion.
  929            * /
  930           pr ivate Stri ng formatD etailDescr iption(Str ing detail Desc, Date  datePoste d) {
  931                    if ( detailDesc  == null)  {
  932                             return  EMPTY_STR ING;
  933                    }
  934  
  935                    Stri ng parsedD esc = deta ilDesc;
  936  
  937                    pars edDesc = p arsedDesc. replace("  FD:", " Fi ll Date: " );
  938                    pars edDesc = p arsedDesc. replace("  RX:", " RX #");
  939                    pars edDesc = p arsedDesc. replace("( NSC)", EMP TY_STRING) ;
  940  
  941                    // F ix for Def ect 680682
  942                    // -  Use the a ctual paym ent posted  date, rep lacing onl y "PAYMENT  (MM/dd/yy yy)"
  943                    // Y iping Yao  - 02/23/20 18
  944                    //
  945                    // F ix for Def ect 711459
  946                    // -  Replace " PAYMENT" w ith "PAYME NT POSTED  ON" follow ed by the  actual pay ment poste d date,
  947                    //    and remov e / ignore  everythin g else aft er the ori ginal "PAY MENT".
  948                    // Y iping Yao  - 04/04/20 18
  949                    if (  datePoste d != null  && detailD esc.starts With("PAYM ENT") )
  950                    //        ( det ailDesc.st artsWith(" PAYMENT")  &&
  951                    //          det ailDesc.co ntains("(" ) &&
  952                    //          det ailDesc.co ntains("/" ) &&
  953                    //          det ailDesc.co ntains("/2 0") &&
  954                    //          det ailDesc.co ntains(")" ) ) )
  955                    {
  956                             final  SimpleDate Format pos tedDateFor mat = new  SimpleDate Format(REP ORT_DATE_F ORMAT);
  957                             parsed Desc = "PA YMENT POST ED ON" + S TRING_SPAC E + posted DateFormat .format(da tePosted);
  958                    }
  959                    //pa rsedDesc =  parsedDes c.replace( "PAYMENT",  "PAYMENT  POSTED ON" );
  960  
  961                    retu rn parsedD esc.trim() ;
  962           }
  963  
  964           /* *
  965            *  Format th e account  number for  easier re adability  as shown o n the exam ples
  966            *  provided  by AITC.
  967            *  
  968            *  @param ac countNumbe r
  969            *              The acco unt number .
  970            *  @return T he formatt ed account  number.
  971            *  @throws I ndexOutOfB oundsExcep tion
  972            *               If an e rror durin g formatti ng an exce ption is t hrown.
  973            * /
  974           pu blic stati c String f ormatAccou ntNumber(f inal Strin g accountN umber) thr ows IndexO utOfBounds Exception  {
  975  
  976                    // T he format  of the acc ount numbe r displaye d on the r eport appe ars to
  977                    // b e:
  978                    // 3  character  site numb er + space  + 3 chara cter + spa ce + 3 cha racter +
  979                    // s pace + 4 c haracter +  space + r emaining c haracter
  980                    Stri ngBuilder  formattedA ccountNumb er = new S tringBuild er();
  981  
  982                    form attedAccou ntNumber.a ppend(subs tringByPos itionLengt h(accountN umber, ACC OUNT_NUMBE R_SPLIT_PO SITION_1,
  983                                      ACCOUNT_ NUMBER_SPL IT_LENGTH_ 1, true));
  984  
  985                    form attedAccou ntNumber.a ppend(STRI NG_SPACE);
  986                    form attedAccou ntNumber.a ppend(subs tringByPos itionLengt h(accountN umber, ACC OUNT_NUMBE R_SPLIT_PO SITION_2,
  987                                      ACCOUNT_ NUMBER_SPL IT_LENGTH_ 2, true));
  988  
  989                    form attedAccou ntNumber.a ppend(STRI NG_SPACE);
  990                    form attedAccou ntNumber.a ppend(subs tringByPos itionLengt h(accountN umber, ACC OUNT_NUMBE R_SPLIT_PO SITION_3,
  991                                      ACCOUNT_ NUMBER_SPL IT_LENGTH_ 3, true));
  992  
  993                    form attedAccou ntNumber.a ppend(STRI NG_SPACE);
  994                    form attedAccou ntNumber.a ppend(subs tringByPos itionLengt h(accountN umber, ACC OUNT_NUMBE R_SPLIT_PO SITION_4,
  995                                      ACCOUNT_ NUMBER_SPL IT_LENGTH_ 4, true));
  996  
  997                    form attedAccou ntNumber.a ppend(STRI NG_SPACE);
  998                    // F ix for Def ect 616442
  999                    // -  Reformat  Account Nu mber
  1000                    // Y iping Yao  - 01/30/20 18
  1001                    form attedAccou ntNumber.a ppend(subs tringByPos itionLengt h(accountN umber, ACC OUNT_NUMBE R_SPLIT_PO SITION_5,
  1002                                      ACCOUNT_ NUMBER_SPL IT_LENGTH_ 5, false)) ;
  1003                    //fo rmattedAcc ountNumber .append(su bstringByP osition(ac countNumbe r, ACCOUNT _NUMBER_SP LIT_POSITI ON_5));
  1004  
  1005                    retu rn formatt edAccountN umber.toSt ring();
  1006           }
  1007  
  1008           /* *
  1009            *  Get a sub string of  the input  string by  the specif ied positi on.
  1010            *  
  1011            *  @param in put
  1012            *              The inpu t string.
  1013            *  @param po sition
  1014            *              The star t position  for the s ubstring.
  1015            *  @return T he substri ng.
  1016            *  @throws I ndexOutOfB oundsExcep tion
  1017            *               If an e rror durin g formatti ng an exce ption is t hrown.
  1018            * /
  1019           /*
  1020           pr ivate stat ic String  substringB yPosition( final Stri ng input,  final int  position)  throws Ind exOutOfBou ndsExcepti on {
  1021  
  1022                    // V erify the  position i s valid fo r the inpu t.
  1023                    if ( (input.len gth() - 1)  < positio n) {
  1024                             throw  new IndexO utOfBounds Exception( "Input ("  + input +  ") with po sition ("  + position  + ") is i nvalid");
  1025                    }
  1026  
  1027                    // G et the sub string.
  1028                    fina l String s s = input. substring( position);
  1029  
  1030                    retu rn ss;
  1031           }
  1032           */
  1033  
  1034           /* *
  1035            *  Get a sub string of  the input  string by  the specif ied positi on and the
  1036            *  desired l ength.
  1037            *  
  1038            *  @param in put
  1039            *              The inpu t string.
  1040            *  @param po sition
  1041            *              The star t position  for the s ubstring
  1042            *  @param le ngth
  1043            *              The leng th of the  substring.
  1044            *  @param ch eckLength
  1045            *              Flag to  indicate i f the resu lt should  be checked  for an er ror.
  1046            *  @return T he substri ng.
  1047            *  @throws I ndexOutOfB oundsExcep tion
  1048            *               If an e rror durin g formatti ng an exce ption is t hrown.
  1049            * /
  1050           pr ivate stat ic String  substringB yPositionL ength(fina l String i nput, fina l int posi tion, fina l int leng th,
  1051                             final  boolean ch eckLength)  throws In dexOutOfBo undsExcept ion {
  1052  
  1053                    // V erify the  position i s valid fo r the inpu t.
  1054                    if ( (input.len gth() - 1)  < positio n) {
  1055                             throw  new IndexO utOfBounds Exception( "Input ("  + input +  ") with po sition ("  + position  + ") is i nvalid");
  1056                    }
  1057  
  1058                    // O ptionally,  verify th e input wi ll support  the subst ring.
  1059                    if ( checkLengt h && ((pos ition + le ngth) > in put.length ())) {
  1060                             throw  new IndexO utOfBounds Exception( "Input ("  + input +  ") will no t support  specified  position ( " + positi on
  1061                                               + ") and l ength (" +  length +  ") substri ng");
  1062                    }
  1063  
  1064                    // G et the sub string.
  1065                    fina l String s s = input. substring( position,  Math.min(p osition +  length, in put.length ()));
  1066  
  1067                    // I f necessar y, check t he length  and if not  the expec ted length  it is
  1068                    // i nvalid.
  1069                    if ( checkLengt h && (ss.l ength() !=  length))  {
  1070                             throw  new IndexO utOfBounds Exception( "Expected  output ("  + ss + ")  with lengt h (" + len gth + ")") ;
  1071                    }
  1072  
  1073                    retu rn ss;
  1074           }
  1075  
  1076           /* *
  1077            *  Create a  string tha t makes th e value re presented  as a credi t.
  1078            *  @param va lue The va lue to con vert.
  1079            *  @return T he credit  representa tion of th e value.
  1080            * /
  1081           pr ivate stat ic String  identifyVa lueAsCredi t(final St ring value ) {
  1082                    retu rn value +  CREDIT_SU FFIX;
  1083           }
  1084  
  1085           //  Fix for D efect 6164 42
  1086           //  - Reforma t Account  Number
  1087           //  Yiping Ya o - 01/30/ 2018
  1088           /* *
  1089            *  Construct  Account N umber:
  1090            *  
  1091            *   Facility  Number (3  digits) +
  1092            *   DFN (13  digits, pa dded with  zero) +
  1093            *   Patientâ €™s Last N ame (5 cha racters, p added with  spaces)
  1094            *  
  1095            * /
  1096           pr ivate Stri ng buildAc countNumbe rDisp(PSPa tient pati ent)
  1097           {
  1098                    if ( patient ==  null)
  1099                    {
  1100                             return  EMPTY_STR ING;
  1101                    }
  1102  
  1103                    Stri ng acntNum Disp = pat ient.getAc ntNumDisp( );
  1104  
  1105                    // T he first 3  digits /  characters  in the or iginal acn tNumDisp a re Facilit y Number
  1106                    Stri ng facilit yNumber =  acntNumDis p.substrin g(ACCOUNT_ NUMBER_SPL IT_POSITIO N_1, ACCOU NT_NUMBER_ SPLIT_LENG TH_1);
  1107  
  1108                    // T he first 3  digits in  DFN numbe r are faci lity numbe r, and the  rest is t he DFN
  1109                    Stri ng dfnNumb er = Strin g.valueOf( patient.ge tDfnNumber ()).substr ing(ACCOUN T_NUMBER_S PLIT_LENGT H_1);
  1110  
  1111                    // T he origina l acntNumD isp = faci lity numbe r (3) + ac count numb er (10) +  last name  (5)
  1112                    Stri ng lastNam e = acntNu mDisp.subs tring(13);
  1113  
  1114                    retu rn String. format("%- 3.3s%013d% -5.5s", fa cilityNumb er, Long.v alueOf(dfn Number), l astName).t rim();
  1115           }
  1116   }