001    /*
002     * Copyright 2011 The Kuali Foundation.
003     * 
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     * http://www.opensource.org/licenses/ecl2.php
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.kfs.pdp.batch.service.impl;
017    
018    import java.io.BufferedWriter;
019    import java.io.FileWriter;
020    import java.io.IOException;
021    import java.sql.Timestamp;
022    import java.text.MessageFormat;
023    import java.text.SimpleDateFormat;
024    import java.util.Date;
025    import java.util.HashMap;
026    import java.util.Iterator;
027    import java.util.List;
028    import java.util.Map;
029    
030    import org.kuali.kfs.pdp.PdpConstants;
031    import org.kuali.kfs.pdp.PdpKeyConstants;
032    import org.kuali.kfs.pdp.batch.service.ExtractPaymentService;
033    import org.kuali.kfs.pdp.businessobject.CustomerProfile;
034    import org.kuali.kfs.pdp.businessobject.PaymentDetail;
035    import org.kuali.kfs.pdp.businessobject.PaymentGroup;
036    import org.kuali.kfs.pdp.businessobject.PaymentGroupHistory;
037    import org.kuali.kfs.pdp.businessobject.PaymentNoteText;
038    import org.kuali.kfs.pdp.businessobject.PaymentProcess;
039    import org.kuali.kfs.pdp.businessobject.PaymentStatus;
040    import org.kuali.kfs.pdp.dataaccess.PaymentGroupHistoryDao;
041    import org.kuali.kfs.pdp.dataaccess.ProcessDao;
042    import org.kuali.kfs.pdp.service.PaymentDetailService;
043    import org.kuali.kfs.pdp.service.PaymentGroupService;
044    import org.kuali.kfs.pdp.service.PdpEmailService;
045    import org.kuali.kfs.sys.businessobject.Bank;
046    import org.kuali.rice.kns.bo.Country;
047    import org.kuali.rice.kns.service.BusinessObjectService;
048    import org.kuali.rice.kns.service.CountryService;
049    import org.kuali.rice.kns.service.DateTimeService;
050    import org.kuali.rice.kns.service.KualiConfigurationService;
051    import org.kuali.rice.kns.service.ParameterService;
052    import org.kuali.rice.kns.util.KualiDecimal;
053    import org.kuali.rice.kns.util.ObjectUtils;
054    import org.springframework.transaction.annotation.Transactional;
055    
056    @Transactional
057    public class ExtractPaymentServiceImpl implements ExtractPaymentService {
058        private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ExtractPaymentServiceImpl.class);
059    
060        protected String directoryName;
061    
062        protected DateTimeService dateTimeService;
063        protected ParameterService parameterService;
064        protected PaymentGroupService paymentGroupService;
065        protected PaymentDetailService paymentDetailService;
066        protected PaymentGroupHistoryDao paymentGroupHistoryDao;
067        protected ProcessDao processDao;
068        protected PdpEmailService paymentFileEmailService;
069        protected BusinessObjectService businessObjectService;
070        protected KualiConfigurationService kualiConfigurationService;
071        protected CountryService countryService;
072    
073        // Set this to true to run this process without updating the database. This
074        // should stay false for production.
075        public static boolean testMode = false;
076    
077        protected String getOutputFile(String fileprefix, Date runDate) {
078            String filename = directoryName + "/" + fileprefix + "_";
079            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
080            filename = filename + sdf.format(runDate);
081            filename = filename + ".xml";
082    
083            return filename;
084        }
085    
086        /**
087         * @see org.kuali.kfs.pdp.batch.service.ExtractPaymentService#extractCancelledChecks()
088         */
089        public void extractCanceledChecks() {
090            LOG.debug("extractCancelledChecks() started");
091    
092            Date processDate = dateTimeService.getCurrentDate();
093            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
094    
095            String checkCancelledFilePrefix = this.kualiConfigurationService.getPropertyString(PdpKeyConstants.ExtractPayment.CHECK_CANCEL_FILENAME);
096            checkCancelledFilePrefix = MessageFormat.format(checkCancelledFilePrefix, new Object[] { null });
097    
098            String filename = getOutputFile(checkCancelledFilePrefix, processDate);
099            LOG.debug("extractCanceledChecks() filename = " + filename);
100    
101            // Open file
102            BufferedWriter os = null;
103    
104            try {
105                os = new BufferedWriter(new FileWriter(filename));
106                os.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
107                writeOpenTag(os, 0, "canceledChecks");
108    
109                Iterator paymentIterator = paymentGroupHistoryDao.getCanceledChecks();
110                while (paymentIterator.hasNext()) {
111                    PaymentGroupHistory history = (PaymentGroupHistory) paymentIterator.next();
112    
113                    writeOpenTag(os, 2, "check");
114    
115                    writeBank(os, 4, history.getPaymentGroup().getBank());
116                    writePayee(os, 4, history.getPaymentGroup());
117    
118                    writeTag(os, 4, "netAmount", history.getPaymentGroup().getNetPaymentAmount().toString());
119                    if (ObjectUtils.isNotNull(history.getOrigDisburseNbr())) {
120                        writeTag(os, 4, "disbursementNumber", history.getOrigDisburseNbr().toString());
121                    }
122                    else {
123                        writeTag(os, 4, "disbursementNumber", history.getPaymentGroup().getDisbursementNbr().toString());
124                    }
125                    if (ObjectUtils.isNotNull(history.getPaymentGroup().getDisbursementType())) {
126                        writeTag(os, 4, "disbursementType", history.getPaymentGroup().getDisbursementType().getCode());
127                    }
128                    else {
129                        writeTag(os, 4, "disbursementType", history.getDisbursementType().getCode());
130                    }
131    
132                    writeCloseTag(os, 2, "check");
133    
134                    if (!testMode) {
135                        history.setLastUpdate(new Timestamp(processDate.getTime()));
136                        history.setPmtCancelExtractDate(new Timestamp(processDate.getTime()));
137                        history.setPmtCancelExtractStat(Boolean.TRUE);
138                        history.setChangeTime(new Timestamp(new Date().getTime()));
139    
140                        this.businessObjectService.save(history);
141                    }
142                }
143    
144                writeCloseTag(os, 0, "canceledChecks");
145            }
146            catch (IOException ie) {
147                LOG.error("extractCanceledChecks() Problem reading file:  " + filename, ie);
148                throw new IllegalArgumentException("Error writing to output file: " + ie.getMessage());
149            }
150            finally {
151                // Close file
152                if (os != null) {
153                    try {
154                        os.close();
155                    }
156                    catch (IOException ie) {
157                        // Not much we can do now
158                    }
159                }
160            }
161        }
162    
163        /**
164         * @see org.kuali.kfs.pdp.batch.service.ExtractPaymentService#extractAchPayments()
165         */
166        public void extractAchPayments() {
167            LOG.debug("extractAchPayments() started");
168    
169            Date processDate = dateTimeService.getCurrentDate();
170            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
171            PaymentStatus extractedStatus = (PaymentStatus) this.businessObjectService.findBySinglePrimaryKey(PaymentStatus.class, PdpConstants.PaymentStatusCodes.EXTRACTED);
172    
173            String achFilePrefix = this.kualiConfigurationService.getPropertyString(PdpKeyConstants.ExtractPayment.ACH_FILENAME);
174            achFilePrefix = MessageFormat.format(achFilePrefix, new Object[] { null });
175    
176            String filename = getOutputFile(achFilePrefix, processDate);
177            LOG.debug("extractAchPayments() filename = " + filename);
178    
179            // Open file
180            BufferedWriter os = null;
181    
182            writeExtractAchFile(extractedStatus, filename, processDate, sdf);
183    
184        }
185    
186        /**
187         * @see org.kuali.kfs.pdp.batch.service.ExtractPaymentService#extractChecks()
188         */
189        public void extractChecks() {
190            LOG.debug("extractChecks() started");
191    
192            Date processDate = dateTimeService.getCurrentDate();
193            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
194            PaymentStatus extractedStatus = (PaymentStatus) this.businessObjectService.findBySinglePrimaryKey(PaymentStatus.class, PdpConstants.PaymentStatusCodes.EXTRACTED);
195    
196            String checkFilePrefix = this.kualiConfigurationService.getPropertyString(PdpKeyConstants.ExtractPayment.CHECK_FILENAME);
197            checkFilePrefix = MessageFormat.format(checkFilePrefix, new Object[] { null });
198    
199            String filename = getOutputFile(checkFilePrefix, processDate);
200            LOG.debug("extractChecks() filename: " + filename);
201    
202            List<PaymentProcess> extractsToRun = this.processDao.getAllExtractsToRun();
203            for (PaymentProcess extractToRun : extractsToRun) {
204                writeExtractCheckFile(extractedStatus, extractToRun, filename, extractToRun.getId().intValue());
205                this.processDao.setExtractProcessAsComplete(extractToRun);
206            }
207        }
208    
209        protected void writeExtractCheckFile(PaymentStatus extractedStatus, PaymentProcess p, String filename, Integer processId) {
210            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
211            Date processDate = dateTimeService.getCurrentDate();
212            BufferedWriter os = null;
213    
214            try {
215                os = new BufferedWriter(new FileWriter(filename));
216                os.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
217                writeOpenTagAttribute(os, 0, "checks", "processId", processId.toString(), "campusCode", p.getCampusCode());
218    
219                List<String> bankCodes = paymentGroupService.getDistinctBankCodesForProcessAndType(processId, PdpConstants.DisbursementTypeCodes.CHECK);
220    
221                for (String bankCode : bankCodes) {
222                    List<Integer> disbNbrs = paymentGroupService.getDisbursementNumbersByDisbursementTypeAndBankCode(processId, PdpConstants.DisbursementTypeCodes.CHECK, bankCode);
223                    for (Iterator<Integer> iter = disbNbrs.iterator(); iter.hasNext();) {
224                        Integer disbursementNbr = iter.next();
225    
226                        boolean first = true;
227    
228                        KualiDecimal totalNetAmount = new KualiDecimal(0);
229    
230                        // this seems wasteful, but since the total net amount is needed on the first payment detail...it's needed
231                        Iterator<PaymentDetail> i2 = paymentDetailService.getByDisbursementNumber(disbursementNbr, processId, PdpConstants.DisbursementTypeCodes.CHECK, bankCode);
232                        while (i2.hasNext()) {
233                            PaymentDetail pd = i2.next();
234                            totalNetAmount = totalNetAmount.add(pd.getNetPaymentAmount());
235                        }
236    
237                        Iterator<PaymentDetail> paymentDetails = paymentDetailService.getByDisbursementNumber(disbursementNbr, processId, PdpConstants.DisbursementTypeCodes.CHECK, bankCode);
238                        while (paymentDetails.hasNext()) {
239                            PaymentDetail pd = paymentDetails.next();
240                            PaymentGroup pg = pd.getPaymentGroup();
241                            if (!testMode) {
242                                pg.setDisbursementDate(new java.sql.Date(processDate.getTime()));
243                                pg.setPaymentStatus(extractedStatus);
244                                this.businessObjectService.save(pg);
245                            }
246    
247                            if (first) {
248                                writeOpenTagAttribute(os, 2, "check", "disbursementNbr", pg.getDisbursementNbr().toString());
249    
250                                // Write check level information
251    
252                                writeBank(os, 4, pg.getBank());
253    
254                                writeTag(os, 4, "disbursementDate", sdf.format(processDate));
255                                writeTag(os, 4, "netAmount", totalNetAmount.toString());
256    
257                                writePayee(os, 4, pg);
258                                writeTag(os, 4, "campusAddressIndicator", pg.getCampusAddress().booleanValue() ? "Y" : "N");
259                                writeTag(os, 4, "attachmentIndicator", pg.getPymtAttachment().booleanValue() ? "Y" : "N");
260                                writeTag(os, 4, "specialHandlingIndicator", pg.getPymtSpecialHandling().booleanValue() ? "Y" : "N");
261                                writeTag(os, 4, "immediatePaymentIndicator", pg.getProcessImmediate().booleanValue() ? "Y" : "N");
262                                writeTag(os, 4, "customerUnivNbr", pg.getCustomerInstitutionNumber());
263                                writeTag(os, 4, "paymentDate", sdf.format(pg.getPaymentDate()));
264    
265                                // Write customer profile information
266                                CustomerProfile cp = pg.getBatch().getCustomerProfile();
267                                writeCustomerProfile(os, 4, cp);
268    
269                                writeOpenTag(os, 4, "payments");
270    
271                            }
272    
273                            writeOpenTag(os, 6, "payment");
274    
275                            writeTag(os, 8, "purchaseOrderNbr", pd.getPurchaseOrderNbr());
276                            writeTag(os, 8, "invoiceNbr", pd.getInvoiceNbr());
277                            writeTag(os, 8, "requisitionNbr", pd.getRequisitionNbr());
278                            writeTag(os, 8, "custPaymentDocNbr", pd.getCustPaymentDocNbr());
279                            writeTag(os, 8, "invoiceDate", sdf.format(pd.getInvoiceDate()));
280    
281                            writeTag(os, 8, "origInvoiceAmount", pd.getOrigInvoiceAmount().toString());
282                            writeTag(os, 8, "netPaymentAmount", pd.getNetPaymentAmount().toString());
283                            writeTag(os, 8, "invTotDiscountAmount", pd.getInvTotDiscountAmount().toString());
284                            writeTag(os, 8, "invTotShipAmount", pd.getInvTotShipAmount().toString());
285                            writeTag(os, 8, "invTotOtherDebitAmount", pd.getInvTotOtherDebitAmount().toString());
286                            writeTag(os, 8, "invTotOtherCreditAmount", pd.getInvTotOtherCreditAmount().toString());
287    
288                            writeOpenTag(os, 8, "notes");
289                            for (Iterator ix = pd.getNotes().iterator(); ix.hasNext();) {
290                                PaymentNoteText note = (PaymentNoteText) ix.next();
291                                writeTag(os, 10, "note", note.getCustomerNoteText());
292                            }
293                            writeCloseTag(os, 8, "notes");
294    
295                            writeCloseTag(os, 6, "payment");
296    
297                            first = false;
298                        }
299                        writeCloseTag(os, 4, "payments");
300                        writeCloseTag(os, 2, "check");
301                    }
302                }
303                writeCloseTag(os, 0, "checks");
304            }
305            catch (IOException ie) {
306                LOG.error("extractChecks() Problem reading file:  " + filename, ie);
307                throw new IllegalArgumentException("Error writing to output file: " + ie.getMessage());
308            }
309            finally {
310                // Close file
311                if (os != null) {
312                    try {
313                        os.close();
314                    }
315                    catch (IOException ie) {
316                        // Not much we can do now
317                    }
318                }
319            }
320        }
321    
322        protected void writeExtractAchFile(PaymentStatus extractedStatus, String filename, Date processDate, SimpleDateFormat sdf) {
323            BufferedWriter os = null;
324            try {
325                os = new BufferedWriter(new FileWriter(filename));
326                os.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
327                writeOpenTag(os, 0, "achPayments");
328    
329                // totals for summary
330                Map<String, Integer> unitCounts = new HashMap<String, Integer>();
331                Map<String, KualiDecimal> unitTotals = new HashMap<String, KualiDecimal>();
332    
333                Iterator iter = paymentGroupService.getByDisbursementTypeStatusCode(PdpConstants.DisbursementTypeCodes.ACH, PdpConstants.PaymentStatusCodes.PENDING_ACH);
334                while (iter.hasNext()) {
335                    PaymentGroup paymentGroup = (PaymentGroup) iter.next();
336                    if (!testMode) {
337                        paymentGroup.setDisbursementDate(new java.sql.Date(processDate.getTime()));
338                        paymentGroup.setPaymentStatus(extractedStatus);
339                        businessObjectService.save(paymentGroup);
340                    }
341    
342                    writeOpenTagAttribute(os, 2, "ach", "disbursementNbr", paymentGroup.getDisbursementNbr().toString());
343                    PaymentProcess paymentProcess = paymentGroup.getProcess();
344                    writeTag(os, 4, "processCampus", paymentProcess.getCampusCode());
345                    writeTag(os, 4, "processId", paymentProcess.getId().toString());
346    
347                    writeBank(os, 4, paymentGroup.getBank());
348    
349                    writeTag(os, 4, "disbursementDate", sdf.format(processDate));
350                    writeTag(os, 4, "netAmount", paymentGroup.getNetPaymentAmount().toString());
351    
352                    writePayeeAch(os, 4, paymentGroup);
353                    writeTag(os, 4, "customerUnivNbr", paymentGroup.getCustomerInstitutionNumber());
354                    writeTag(os, 4, "paymentDate", sdf.format(paymentGroup.getPaymentDate()));
355    
356                    // Write customer profile information
357                    CustomerProfile cp = paymentGroup.getBatch().getCustomerProfile();
358                    writeCustomerProfile(os, 4, cp);
359    
360                    // Write all payment level information
361                    writeOpenTag(os, 4, "payments");
362                    List pdList = paymentGroup.getPaymentDetails();
363                    for (Iterator iterator = pdList.iterator(); iterator.hasNext();) {
364                        PaymentDetail paymentDetail = (PaymentDetail) iterator.next();
365                        writeOpenTag(os, 6, "payment");
366    
367                        // Write detail info
368                        writeTag(os, 6, "purchaseOrderNbr", paymentDetail.getPurchaseOrderNbr());
369                        writeTag(os, 6, "invoiceNbr", paymentDetail.getInvoiceNbr());
370                        writeTag(os, 6, "requisitionNbr", paymentDetail.getRequisitionNbr());
371                        writeTag(os, 6, "custPaymentDocNbr", paymentDetail.getCustPaymentDocNbr());
372                        writeTag(os, 6, "invoiceDate", sdf.format(paymentDetail.getInvoiceDate()));
373    
374                        writeTag(os, 6, "origInvoiceAmount", paymentDetail.getOrigInvoiceAmount().toString());
375                        writeTag(os, 6, "netPaymentAmount", paymentDetail.getNetPaymentAmount().toString());
376                        writeTag(os, 6, "invTotDiscountAmount", paymentDetail.getInvTotDiscountAmount().toString());
377                        writeTag(os, 6, "invTotShipAmount", paymentDetail.getInvTotShipAmount().toString());
378                        writeTag(os, 6, "invTotOtherDebitAmount", paymentDetail.getInvTotOtherDebitAmount().toString());
379                        writeTag(os, 6, "invTotOtherCreditAmount", paymentDetail.getInvTotOtherCreditAmount().toString());
380    
381                        writeOpenTag(os, 6, "notes");
382                        for (Iterator i = paymentDetail.getNotes().iterator(); i.hasNext();) {
383                            PaymentNoteText note = (PaymentNoteText) i.next();
384                            writeTag(os, 8, "note", escapeString(note.getCustomerNoteText()));
385                        }
386                        writeCloseTag(os, 6, "notes");
387    
388                        writeCloseTag(os, 4, "payment");
389    
390                        String unit = paymentGroup.getBatch().getCustomerProfile().getChartCode() + "-" + paymentGroup.getBatch().getCustomerProfile().getUnitCode() + "-" + paymentGroup.getBatch().getCustomerProfile().getSubUnitCode();
391    
392                        Integer count = 1;
393                        if (unitCounts.containsKey(unit)) {
394                            count = 1 + unitCounts.get(unit);
395                        }
396                        unitCounts.put(unit, count);
397    
398                        KualiDecimal unitTotal = paymentDetail.getNetPaymentAmount();
399                        if (unitTotals.containsKey(unit)) {
400                            unitTotal = paymentDetail.getNetPaymentAmount().add(unitTotals.get(unit));
401                        }
402                        unitTotals.put(unit, unitTotal);
403                    }
404    
405                    writeCloseTag(os, 4, "payments");
406                    writeCloseTag(os, 2, "ach");
407                }
408                writeCloseTag(os, 0, "achPayments");
409    
410                // send summary email
411                paymentFileEmailService.sendAchSummaryEmail(unitCounts, unitTotals, dateTimeService.getCurrentDate());
412            }
413            catch (IOException ie) {
414                LOG.error("extractAchPayments() Problem reading file:  " + filename, ie);
415                throw new IllegalArgumentException("Error writing to output file: " + ie.getMessage());
416            }
417            finally {
418                // Close file
419                if (os != null) {
420                    try {
421                        os.close();
422                    }
423                    catch (IOException ie) {
424                        // Not much we can do now
425                    }
426                }
427            }
428        }
429    
430        protected static String SPACES = "                                                       ";
431    
432        protected void writeTag(BufferedWriter os, int indent, String tag, String data) throws IOException {
433            if (data != null) {
434                os.write(SPACES.substring(0, indent));
435                os.write("<" + tag + ">" + escapeString(data) + "</" + tag + ">\n");
436            }
437        }
438    
439        protected void writeOpenTag(BufferedWriter os, int indent, String tag) throws IOException {
440            os.write(SPACES.substring(0, indent));
441            os.write("<" + tag + ">\n");
442        }
443    
444        protected void writeOpenTagAttribute(BufferedWriter os, int indent, String tag, String attr, String attrVal) throws IOException {
445            os.write(SPACES.substring(0, indent));
446            os.write("<" + tag + " " + attr + "=\"" + escapeString(attrVal) + "\">\n");
447        }
448    
449        protected void writeOpenTagAttribute(BufferedWriter os, int indent, String tag, String attr1, String attr1Val, String attr2, String attr2Val) throws IOException {
450            os.write(SPACES.substring(0, indent));
451            os.write("<" + tag + " " + attr1 + "=\"" + escapeString(attr1Val) + "\" " + attr2 + "=\"" + escapeString(attr2Val) + "\">\n");
452        }
453    
454        protected void writeCloseTag(BufferedWriter os, int indent, String tag) throws IOException {
455            os.write(SPACES.substring(0, indent));
456            os.write("</" + tag + ">\n");
457        }
458    
459        protected void writeBank(BufferedWriter os, int indent, Bank b) throws IOException {
460            if (b != null) {
461                writeOpenTagAttribute(os, indent, "bank", "code", b.getBankCode());
462                writeTag(os, indent + 2, "accountNumber", b.getBankAccountNumber());
463                writeTag(os, indent + 2, "routingNumber", b.getBankRoutingNumber());
464                writeCloseTag(os, indent, "bank");
465            }
466        }
467    
468        protected void writeCustomerProfile(BufferedWriter os, int indent, CustomerProfile cp) throws IOException {
469            writeOpenTag(os, indent, "customerProfile");
470            writeTag(os, indent + 2, "chartCode", cp.getChartCode());
471            writeTag(os, indent + 2, "orgCode", cp.getUnitCode());
472            writeTag(os, indent + 2, "subUnitCode", cp.getSubUnitCode());
473            writeOpenTag(os, indent + 2, "checkHeaderNoteLines");
474            writeTag(os, indent + 4, "note", cp.getCheckHeaderNoteTextLine1());
475            writeTag(os, indent + 4, "note", cp.getCheckHeaderNoteTextLine2());
476            writeTag(os, indent + 4, "note", cp.getCheckHeaderNoteTextLine3());
477            writeTag(os, indent + 4, "note", cp.getCheckHeaderNoteTextLine4());
478            writeCloseTag(os, indent + 2, "checkHeaderNoteLines");
479            writeOpenTag(os, indent + 2, "additionalCheckNoteLines");
480            writeTag(os, indent + 4, "note", cp.getAdditionalCheckNoteTextLine1());
481            writeTag(os, indent + 4, "note", cp.getAdditionalCheckNoteTextLine2());
482            writeTag(os, indent + 4, "note", cp.getAdditionalCheckNoteTextLine3());
483            writeTag(os, indent + 4, "note", cp.getAdditionalCheckNoteTextLine4());
484            writeCloseTag(os, indent + 2, "additionalCheckNoteLines");
485            writeCloseTag(os, indent, "customerProfile");
486        }
487    
488        protected void writePayeeAch(BufferedWriter os, int indent, PaymentGroup pg) throws IOException {
489            writePayeeInformation(os, indent, pg, true);
490        }
491    
492        protected void writePayee(BufferedWriter os, int indent, PaymentGroup pg) throws IOException {
493            writePayeeInformation(os, indent, pg, false);
494        }
495    
496        protected void writePayeeInformation(BufferedWriter os, int indent, PaymentGroup pg, boolean includeAch) throws IOException {
497            os.write(SPACES.substring(0, indent));
498            os.write("<payee id=\"" + pg.getPayeeId() + "\" type=\"" + pg.getPayeeIdTypeCd() + "\">\n");
499            writeTag(os, indent + 2, "payeeName", pg.getPayeeName());
500            writeTag(os, indent + 2, "line1Address", pg.getLine1Address());
501            writeTag(os, indent + 2, "line2Address", pg.getLine2Address());
502            writeTag(os, indent + 2, "line3Address", pg.getLine3Address());
503            writeTag(os, indent + 2, "line4Address", pg.getLine4Address());
504            writeTag(os, indent + 2, "city", pg.getCity());
505            writeTag(os, indent + 2, "state", pg.getState());
506            writeTag(os, indent + 2, "zipCd", pg.getZipCd());
507            
508            // get country name for code
509            Country country = countryService.getByPrimaryId(pg.getCountry());
510            if (country != null) {
511                writeTag(os, indent + 2, "country", country.getPostalCountryName());
512            }
513            else {
514                writeTag(os, indent + 2, "country", pg.getCountry());
515            }
516    
517            if (includeAch) {
518                writeTag(os, indent + 2, "achBankRoutingNbr", pg.getAchBankRoutingNbr());
519                writeTag(os, indent + 2, "achBankAccountNbr", pg.getAchAccountNumber().getAchBankAccountNbr());
520                writeTag(os, indent + 2, "achAccountType", pg.getAchAccountType());
521            }
522            writeCloseTag(os, indent, "payee");
523        }
524    
525        protected String escapeString(String input) {
526            String output = input.replaceAll("\\&", "&amp;");
527            output = output.replaceAll("\"", "&quot;");
528            output = output.replaceAll("\\'", "&apos;");
529            output = output.replaceAll("\\<", "&lt;");
530            output = output.replaceAll("\\>", "&gt;");
531            return output;
532        }
533    
534        /**
535         * Sets the directoryName attribute value.
536         * 
537         * @param directoryName The directoryName to set.
538         */
539        public void setDirectoryName(String directoryName) {
540            this.directoryName = directoryName;
541        }
542    
543    
544        /**
545         * Sets the dateTimeService attribute value.
546         * 
547         * @param dateTimeService The dateTimeService to set.
548         */
549        public void setDateTimeService(DateTimeService dateTimeService) {
550            this.dateTimeService = dateTimeService;
551        }
552    
553        /**
554         * Sets the parameterService attribute value.
555         * 
556         * @param parameterService The parameterService to set.
557         */
558        public void setParameterService(ParameterService parameterService) {
559            this.parameterService = parameterService;
560        }
561    
562        /**
563         * Sets the paymentGroupService attribute value.
564         * 
565         * @param paymentGroupService The paymentGroupService to set.
566         */
567        public void setPaymentGroupService(PaymentGroupService paymentGroupService) {
568            this.paymentGroupService = paymentGroupService;
569        }
570    
571        /**
572         * Sets the paymentDetailService attribute value.
573         * 
574         * @param paymentDetailService The paymentDetailService to set.
575         */
576        public void setPaymentDetailService(PaymentDetailService paymentDetailService) {
577            this.paymentDetailService = paymentDetailService;
578        }
579    
580        /**
581         * Sets the paymentGroupHistoryDao attribute value.
582         * 
583         * @param paymentGroupHistoryDao The paymentGroupHistoryDao to set.
584         */
585        public void setPaymentGroupHistoryDao(PaymentGroupHistoryDao paymentGroupHistoryDao) {
586            this.paymentGroupHistoryDao = paymentGroupHistoryDao;
587        }
588    
589        /**
590         * Sets the processDao attribute value.
591         * 
592         * @param processDao The processDao to set.
593         */
594        public void setProcessDao(ProcessDao processDao) {
595            this.processDao = processDao;
596        }
597    
598        /**
599         * Sets the paymentFileEmailService attribute value.
600         * 
601         * @param paymentFileEmailService The paymentFileEmailService to set.
602         */
603        public void setPaymentFileEmailService(PdpEmailService paymentFileEmailService) {
604            this.paymentFileEmailService = paymentFileEmailService;
605        }
606    
607        /**
608         * Sets the business object service
609         * 
610         * @param businessObjectService
611         */
612        public void setBusinessObjectService(BusinessObjectService businessObjectService) {
613            this.businessObjectService = businessObjectService;
614        }
615    
616        public void setKualiConfigurationService(KualiConfigurationService kualiConfigurationService) {
617            this.kualiConfigurationService = kualiConfigurationService;
618        }
619    
620        /**
621         * Gets the countryService attribute.
622         * 
623         * @return Returns the countryService.
624         */
625        protected CountryService getCountryService() {
626            return countryService;
627        }
628    
629        /**
630         * Sets the countryService attribute value.
631         * 
632         * @param countryService The countryService to set.
633         */
634        public void setCountryService(CountryService countryService) {
635            this.countryService = countryService;
636        }
637    
638    
639    }