001/*
002 * Copyright 2008 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 */
016package org.kuali.ole.module.purap.service.impl;
017
018import org.apache.commons.lang.ArrayUtils;
019import org.apache.commons.lang.StringUtils;
020import org.apache.commons.lang.builder.ToStringBuilder;
021import org.apache.log4j.Logger;
022import org.kuali.ole.module.purap.PurapConstants;
023import org.kuali.ole.module.purap.businessobject.*;
024import org.kuali.ole.module.purap.document.ElectronicInvoiceRejectDocument;
025import org.kuali.ole.module.purap.document.PurchaseOrderDocument;
026import org.kuali.ole.module.purap.util.ElectronicInvoiceUtils;
027import org.kuali.ole.sys.context.SpringContext;
028import org.kuali.rice.core.api.datetime.DateTimeService;
029import org.kuali.rice.krad.util.GlobalVariables;
030
031import java.math.BigDecimal;
032import java.sql.Date;
033import java.text.ParseException;
034import java.util.ArrayList;
035import java.util.HashMap;
036import java.util.List;
037import java.util.Map;
038
039/**
040 * This is a holder class which can be passed to the matching service to validate einvoice or reject doc data
041 * against the po document.
042 */
043
044public class ElectronicInvoiceOrderHolder {
045
046    private final static Logger LOG = Logger.getLogger(ElectronicInvoiceOrderHolder.class);
047
048    private ElectronicInvoiceRejectDocument rejectDocument;
049    private ElectronicInvoiceOrder invoiceOrder;
050    private ElectronicInvoice eInvoice;
051    private PurchaseOrderDocument poDocument;
052    private Map<String, ElectronicInvoiceItemMapping> itemTypeMappings;
053    private Map<String, ItemType> kualiItemTypes;
054
055    private Map<String, FieldErrorHelper> errorFieldDetails = new HashMap<String, FieldErrorHelper>();
056
057    private List<ElectronicInvoiceItemHolder> items = new ArrayList<ElectronicInvoiceItemHolder>();
058
059    private boolean isRejected = false;
060    private boolean isRejectDocumentHolder;
061    private boolean validateHeader;
062
063    private String[] summaryRejectCodes = new String[]{PurapConstants.ElectronicInvoice.TAX_SUMMARY_AMT_MISMATCH,
064            PurapConstants.ElectronicInvoice.SHIPPING_SUMMARY_AMT_MISMATCH,
065            PurapConstants.ElectronicInvoice.SPL_HANDLING_SUMMARY_AMT_MISMATCH,
066            PurapConstants.ElectronicInvoice.DISCOUNT_SUMMARY_AMT_MISMATCH};
067
068    public ElectronicInvoiceOrderHolder(ElectronicInvoiceRejectDocument rejectDocument,
069                                        Map itemTypeMappings,
070                                        Map itemTypes) {
071
072        /**
073         * This class has been designed based on good citizen pattern.
074         */
075        if (rejectDocument == null) {
076            throw new NullPointerException("ElectronicInvoiceRejectDocument should not be null");
077        }
078
079        this.rejectDocument = rejectDocument;
080        this.itemTypeMappings = itemTypeMappings;
081        this.poDocument = rejectDocument.getCurrentPurchaseOrderDocument();
082        this.kualiItemTypes = itemTypes;
083
084        isRejectDocumentHolder = true;
085        validateHeader = true;
086
087        for (int i = 0; i < rejectDocument.getInvoiceRejectItems().size(); i++) {
088
089            ElectronicInvoiceRejectItem invoiceRejectItem = rejectDocument.getInvoiceRejectItems().get(i);
090
091            PurApItem poItem = null;
092            if (poDocument != null) {
093                try {
094                    poItem = poDocument.getItemByLineNumber(invoiceRejectItem.getInvoiceReferenceItemLineNumber());
095                } catch (NullPointerException e) {
096                    /**
097                     * Not needed to handle this invalid item here, this will be handled in the matching process 
098                     */
099                }
100            }
101
102            items.add(new ElectronicInvoiceItemHolder(invoiceRejectItem, itemTypeMappings, poItem == null ? null : (PurchaseOrderItem) poItem, this));
103        }
104
105        /**
106         * It's needed to retain any reject reasons which are related to summary amount matching
107         * which should not escape from the matching process 
108         */
109        retainSummaryRejects(rejectDocument);
110
111    }
112
113    protected void retainSummaryRejects(ElectronicInvoiceRejectDocument rejectDocument) {
114
115        if (LOG.isInfoEnabled()) {
116            LOG.info("Searching for summary rejects");
117        }
118
119        List<ElectronicInvoiceRejectReason> retainList = new ArrayList<ElectronicInvoiceRejectReason>();
120        List<ElectronicInvoiceRejectReason> rejectReasons = rejectDocument.getInvoiceRejectReasons();
121
122        for (int i = 0; i < rejectReasons.size(); i++) {
123            if (ArrayUtils.contains(summaryRejectCodes, rejectReasons.get(i).getInvoiceRejectReasonTypeCode())) {
124                retainList.add(rejectReasons.get(i));
125                if (LOG.isInfoEnabled()) {
126                    LOG.info("Retaining Reject [Code=" + rejectReasons.get(i).getInvoiceRejectReasonTypeCode() + ",Desc=" + rejectReasons.get(i).getInvoiceRejectReasonDescription());
127                }
128            }
129        }
130
131        if (LOG.isInfoEnabled()) {
132            if (retainList.size() == 0) {
133                LOG.info("No summary rejects found");
134            }
135        }
136
137        /**
138         * FIXME: Use rejectDocument.getInvoiceRejectReasons().remove(index) instead of creating a new list
139         */
140        rejectDocument.getInvoiceRejectReasons().clear();
141
142        for (int i = 0; i < retainList.size(); i++) {
143            rejectDocument.addRejectReason(retainList.get(i));
144        }
145    }
146
147
148    public ElectronicInvoiceOrderHolder(ElectronicInvoice eInvoice,
149                                        ElectronicInvoiceOrder invoiceOrder,
150                                        PurchaseOrderDocument poDocument,
151                                        Map itemTypeMappings,
152                                        Map itemTypes,
153                                        boolean validateHeader) {
154
155        if (eInvoice == null) {
156            throw new NullPointerException("ElectronicInvoice should not be null");
157        }
158
159        if (invoiceOrder == null) {
160            throw new NullPointerException("ElectronicInvoiceOrder should not be null");
161        }
162
163        this.eInvoice = eInvoice;
164        this.invoiceOrder = invoiceOrder;
165        this.itemTypeMappings = itemTypeMappings;
166        this.validateHeader = validateHeader;
167        this.kualiItemTypes = itemTypes;
168
169        this.poDocument = poDocument;
170
171        isRejectDocumentHolder = false;
172
173        for (int i = 0; i < invoiceOrder.getInvoiceItems().size(); i++) {
174
175            ElectronicInvoiceItem orderItem = invoiceOrder.getInvoiceItems().get(i);
176
177            PurApItem poItem = null;
178            if (poDocument != null) {
179                try {
180                    poItem = poDocument.getItemByLineNumber(orderItem.getReferenceLineNumberInteger());
181                } catch (NullPointerException e) {
182                    /**
183                     * Not needed to handle this invalid item here, this will be handled in the matching process 
184                     */
185                }
186            }
187
188            items.add(new ElectronicInvoiceItemHolder(orderItem, itemTypeMappings, poItem == null ? null : (PurchaseOrderItem) poItem, this));
189        }
190
191    }
192
193    public String getFileName() {
194        if (isRejectDocumentHolder()) {
195            return rejectDocument.getInvoiceFileName();
196        } else {
197            return eInvoice.getFileName();
198        }
199    }
200
201    public String getDunsNumber() {
202        if (isRejectDocumentHolder()) {
203            return rejectDocument.getVendorDunsNumber();
204        } else {
205            return eInvoice.getDunsNumber();
206        }
207    }
208
209    public String getCustomerNumber() {
210        if (isRejectDocumentHolder()) {
211            return rejectDocument.getInvoiceCustomerNumber();
212        } else {
213            return eInvoice.getCustomerNumber();
214        }
215    }
216
217    public Integer getVendorHeaderId() {
218        if (isRejectDocumentHolder()) {
219            return rejectDocument.getVendorHeaderGeneratedIdentifier();
220        } else {
221            return eInvoice.getVendorHeaderID();
222        }
223    }
224
225    public Integer getVendorDetailId() {
226        if (isRejectDocumentHolder()) {
227            return rejectDocument.getVendorDetailAssignedIdentifier();
228        } else {
229            return eInvoice.getVendorDetailID();
230        }
231    }
232
233    public String getVendorName() {
234        if (isRejectDocumentHolder()) {
235            if (rejectDocument.getVendorDetail() != null) {
236                return rejectDocument.getVendorDetail().getVendorName();
237            } else {
238                return StringUtils.EMPTY;
239            }
240        } else {
241            return eInvoice.getVendorName();
242        }
243    }
244
245    public String getInvoiceNumber() {
246        if (isRejectDocumentHolder()) {
247            return rejectDocument.getInvoiceFileNumber();
248        } else {
249            return eInvoice.getInvoiceDetailRequestHeader().getInvoiceId();
250        }
251    }
252
253    public Date getInvoiceDate() {
254        if (isRejectDocumentHolder()) {
255            return ElectronicInvoiceUtils.getDate(rejectDocument.getInvoiceFileDate());
256        } else {
257            return eInvoice.getInvoiceDetailRequestHeader().getInvoiceDate();
258        }
259    }
260
261    public String getInvoiceDateString() {
262        if (isRejectDocumentHolder()) {
263            return rejectDocument.getInvoiceFileDate();
264        } else {
265            return eInvoice.getInvoiceDetailRequestHeader().getInvoiceDateString();
266        }
267    }
268
269
270    public boolean isInformationOnly() {
271        if (isRejectDocumentHolder()) {
272            return rejectDocument.isInvoiceFileInformationOnlyIndicator();
273        } else {
274            return eInvoice.getInvoiceDetailRequestHeader().isInformationOnly();
275        }
276    }
277
278    public String getInvoicePurchaseOrderID() {
279        if (isRejectDocumentHolder()) {
280            return rejectDocument.getInvoicePurchaseOrderNumber();
281        } else {
282            return invoiceOrder.getOrderReferenceOrderID();
283        }
284    }
285
286    public boolean isTaxInLine() {
287        if (isRejectDocumentHolder()) {
288            return rejectDocument.isInvoiceFileTaxInLineIndicator();
289        } else {
290            return eInvoice.getInvoiceDetailRequestHeader().isTaxInLine();
291        }
292    }
293
294    public BigDecimal getTaxAmount() {
295        if (isRejectDocumentHolder()) {
296            return rejectDocument.getInvoiceItemTaxAmount();
297        } else {
298            return eInvoice.getInvoiceTaxAmount(invoiceOrder);
299        }
300    }
301
302    public String getTaxDescription() {
303        if (isRejectDocumentHolder()) {
304            return rejectDocument.getInvoiceItemTaxDescription();
305        } else {
306            return eInvoice.getInvoiceTaxDescription(invoiceOrder);
307        }
308    }
309
310    public boolean isSpecialHandlingInLine() {
311        if (isRejectDocumentHolder()) {
312            return rejectDocument.isInvoiceFileSpecialHandlingInLineIndicator();
313        } else {
314            return eInvoice.getInvoiceDetailRequestHeader().isSpecialHandlingInLine();
315        }
316    }
317
318    public BigDecimal getInvoiceSpecialHandlingAmount() {
319        if (isRejectDocumentHolder()) {
320            return rejectDocument.getInvoiceItemSpecialHandlingAmount();
321        } else {
322            return eInvoice.getInvoiceSpecialHandlingAmount(invoiceOrder);
323        }
324    }
325
326    public String getInvoiceSpecialHandlingDescription() {
327        if (isRejectDocumentHolder()) {
328            return rejectDocument.getInvoiceItemSpecialHandlingDescription();
329        } else {
330            return eInvoice.getInvoiceSpecialHandlingDescription(invoiceOrder);
331        }
332    }
333
334    public boolean isShippingInLine() {
335        if (isRejectDocumentHolder()) {
336            return rejectDocument.isInvoiceFileShippingInLineIndicator();
337        } else {
338            return eInvoice.getInvoiceDetailRequestHeader().isShippingInLine();
339        }
340    }
341
342    public BigDecimal getInvoiceShippingAmount() {
343        if (isRejectDocumentHolder()) {
344            return rejectDocument.getInvoiceItemShippingAmount();
345        } else {
346            return eInvoice.getInvoiceShippingAmount(invoiceOrder);
347        }
348    }
349
350    public String getInvoiceShippingDescription() {
351        if (isRejectDocumentHolder()) {
352            return rejectDocument.getInvoiceItemShippingDescription();
353        } else {
354            return eInvoice.getInvoiceShippingDescription(invoiceOrder);
355        }
356    }
357
358    public boolean isDiscountInLine() {
359        if (isRejectDocumentHolder()) {
360            return rejectDocument.isInvoiceFileDiscountInLineIndicator();
361        } else {
362            return eInvoice.getInvoiceDetailRequestHeader().isDiscountInLine();
363        }
364    }
365
366    public BigDecimal getInvoiceDiscountAmount() {
367        if (isRejectDocumentHolder()) {
368            return rejectDocument.getInvoiceItemDiscountAmount();
369        } else {
370            return eInvoice.getInvoiceDiscountAmount(invoiceOrder);
371        }
372    }
373
374    public BigDecimal getInvoiceDepositAmount() {
375        if (isRejectDocumentHolder()) {
376            throw new UnsupportedOperationException("Deposit amount not available for the reject document");
377        } else {
378            return eInvoice.getInvoiceDepositAmount();
379        }
380    }
381
382    public BigDecimal getInvoiceDueAmount() {
383        if (isRejectDocumentHolder()) {
384            throw new UnsupportedOperationException("Deposit amount not available for the reject document");
385        } else {
386            return eInvoice.getInvoiceDueAmount();
387        }
388    }
389
390    public PurchaseOrderDocument getPurchaseOrderDocument() {
391        return poDocument;
392    }
393
394    public ElectronicInvoiceItemHolder[] getItems() {
395        if (items != null) {
396            ElectronicInvoiceItemHolder[] returnItems = new ElectronicInvoiceItemHolder[items.size()];
397            items.toArray(returnItems);
398            return returnItems;
399        }
400        return null;
401    }
402
403    public ElectronicInvoiceItemHolder getItemByLineNumber(int lineNumber) {
404
405        if (items != null) {
406            for (int i = 0; i < items.size(); i++) {
407                ElectronicInvoiceItemHolder itemHolder = items.get(i);
408                if (itemHolder.getInvoiceItemLineNumber().intValue() == lineNumber) {
409                    return itemHolder;
410                }
411            }
412        }
413        return null;
414    }
415
416    public void addInvoiceHeaderRejectReason(ElectronicInvoiceRejectReason rejectReason) {
417        addInvoiceHeaderRejectReason(rejectReason, null, null);
418    }
419
420    public void addInvoiceHeaderRejectReason(ElectronicInvoiceRejectReason rejectReason,
421                                             String fieldName,
422                                             String applnResourceKey) {
423
424        if (LOG.isInfoEnabled()) {
425            LOG.info("Adding reject reason - " + rejectReason.getInvoiceRejectReasonDescription());
426        }
427
428        if (isRejectDocumentHolder()) {
429            rejectDocument.addRejectReason(rejectReason);
430            if (fieldName != null && applnResourceKey != null) {
431                /**
432                 * FIXME : Create a helper method to get the fieldname and key name in the resource bundle
433                 * for a specific reject reason type code instead of getting it from the 
434                 * calling method. Matching service should not do these things. It should 
435                 * not know whether it's doing the matching process for a reject doc or for einvoice. It should
436                 * be independent of the incoming data
437                 *
438                 */
439                GlobalVariables.getMessageMap().putError(fieldName, applnResourceKey);
440            }
441        } else {
442            eInvoice.addFileRejectReasonToList(rejectReason);
443            eInvoice.setFileRejected(true);
444        }
445    }
446
447    public void addInvoiceOrderRejectReason(ElectronicInvoiceRejectReason rejectReason,
448                                            String fieldName) {
449        addInvoiceOrderRejectReason(rejectReason, fieldName, null);
450    }
451
452    public void addInvoiceOrderRejectReason(ElectronicInvoiceRejectReason rejectReason,
453                                            String fieldName,
454                                            String applnResourceKey) {
455
456        if (LOG.isInfoEnabled()) {
457            LOG.info("Adding reject reason - " + rejectReason.getInvoiceRejectReasonDescription());
458        }
459
460        if (isRejectDocumentHolder()) {
461            rejectDocument.addRejectReason(rejectReason);
462            if (fieldName != null && applnResourceKey != null) {
463                /**
464                 * FIXME : Create a helper method to get the fieldname and key name in the resource bundle
465                 * for a specific reject reason type code instead of getting it from the 
466                 * calling method. Matching service should not do these things. It should 
467                 * not know whether it's doing the matching process for a reject doc or for einvoice. It should
468                 * be independent of the incoming data
469                 *
470                 * Also, needs to analyze the way of handling errors in specific line item
471                 */
472                GlobalVariables.getMessageMap().putError(fieldName, applnResourceKey);
473            }
474        } else {
475            invoiceOrder.addRejectReasonToList(rejectReason);
476            eInvoice.setFileRejected(true);
477        }
478    }
479
480    public void addInvoiceOrderRejectReason(ElectronicInvoiceRejectReason rejectReason) {
481        addInvoiceOrderRejectReason(rejectReason, null, null);
482    }
483
484    public boolean isValidateHeaderInformation() {
485        return validateHeader;
486    }
487
488    public boolean isRejectDocumentHolder() {
489        return isRejectDocumentHolder;
490    }
491
492    public ElectronicInvoiceItemMapping getInvoiceItemMapping(String invoiceItemTypeCode) {
493        if (itemTypeMappings == null) {
494            return null;
495        } else {
496            return itemTypeMappings.get(invoiceItemTypeCode);
497        }
498    }
499    
500    /*public boolean isItemTypeAvailableInKuali(String invoiceItemTypeCode) {
501        if (itemTypeMappings == null) {
502            return false;
503        }
504        else {
505            return itemTypeMappings.containsKey(invoiceItemTypeCode);
506        }
507    }*/
508
509    public boolean isItemTypeAvailableInItemMapping(String invoiceItemTypeCode) {
510        if (itemTypeMappings == null) {
511            return false;
512        } else {
513            return itemTypeMappings.containsKey(invoiceItemTypeCode);
514        }
515    }
516
517
518    public boolean isInvoiceRejected() {
519        if (isRejectDocumentHolder()) {
520            return rejectDocument.getInvoiceRejectReasons() != null && rejectDocument.getInvoiceRejectReasons().size() > 0;
521        } else {
522            return eInvoice.isFileRejected();
523        }
524    }
525
526
527    public String getKualiItemTypeCodeFromMappings(String invoiceItemTypeCode) {
528
529        ElectronicInvoiceItemMapping itemMapping = getInvoiceItemMapping(invoiceItemTypeCode);
530
531        if (itemMapping != null) {
532            return itemMapping.getItemTypeCode();
533        } else {
534            return null;
535        }
536    }
537    
538   /* public String getKualiItemTypeCode(String invoiceItemTypeCode) {
539        
540        ItemType itemType = kualiItemTypes.get(invoiceItemTypeCode);
541        
542        if (itemType != null) {
543            return itemType.getItemTypeCode();
544        }
545        else {
546            return null;
547        }
548    }*/
549    
550   /* public boolean isKualiItemTypeExistsInVendorItemTypeMappings(String kualiItemType){
551        ElectronicInvoiceItemMapping[] mappings = getInvoiceItemTypeMappings();
552        if (mappings != null){
553            for (int i = 0; i < mappings.length; i++) {
554                if (StringUtils.equals(kualiItemType,mappings[i].getItemTypeCode())){
555                    return true;
556                }
557            }
558        }
559        
560        return false;
561    }*/
562
563    public ElectronicInvoiceItemMapping[] getInvoiceItemTypeMappings() {
564        if (itemTypeMappings != null) {
565            ElectronicInvoiceItemMapping[] itemMappings = new ElectronicInvoiceItemMapping[itemTypeMappings.size()];
566            itemTypeMappings.values().toArray(itemMappings);
567            return itemMappings;
568        } else {
569            return null;
570        }
571    }
572
573    public boolean isInvoiceNumberAcceptIndicatorEnabled() {
574        if (isRejectDocumentHolder()) {
575            return rejectDocument.isInvoiceNumberAcceptIndicator();
576        } else {
577            return false;
578        }
579    }
580
581    public ElectronicInvoice getElectronicInvoice() {
582        if (isRejectDocumentHolder()) {
583            throw new UnsupportedOperationException("ElectronicInvoice object not available for ElectronicInvoiceRejectDocument");
584        } else {
585            return eInvoice;
586        }
587    }
588
589    public BigDecimal getInvoiceNetAmount() {
590        if (isRejectDocumentHolder()) {
591            return rejectDocument.getInvoiceItemNetAmount();
592        } else {
593            return eInvoice.getInvoiceNetAmount(invoiceOrder);
594        }
595    }
596
597    public Date getInvoiceProcessedDate() {
598        DateTimeService dateTimeService = SpringContext.getBean(DateTimeService.class);
599        if (isRejectDocumentHolder()) {
600            try {
601                return dateTimeService.convertToSqlDate(rejectDocument.getInvoiceProcessTimestamp());
602            } catch (ParseException e) {
603                throw new RuntimeException("ParseException thrown when trying to convert a Timestamp to SqlDate.", e);
604            }
605        } else {
606            return dateTimeService.getCurrentSqlDate();
607        }
608    }
609
610    public String getInvoiceShipToAddressAsString() {
611
612        StringBuffer noteBuffer = new StringBuffer();
613        noteBuffer.append("Shipping Address from Electronic Invoice:\n\n");
614
615        if (!isRejectDocumentHolder()) {
616
617            ElectronicInvoicePostalAddress shipToAddress = eInvoice.getCxmlPostalAddress(invoiceOrder, PurapConstants.ElectronicInvoice.CXML_ADDRESS_SHIP_TO_ROLE_ID, PurapConstants.ElectronicInvoice.CXML_ADDRESS_SHIP_TO_NAME);
618            if (shipToAddress != null) {
619
620                if (StringUtils.isNotEmpty(shipToAddress.getName())) {
621                    noteBuffer.append(shipToAddress.getName() + "\n");
622                }
623
624                noteBuffer.append(shipToAddress.getLine1() + "\n");
625
626                if (StringUtils.isNotEmpty(shipToAddress.getLine2())) {
627                    noteBuffer.append(shipToAddress.getLine2() + "\n");
628                }
629
630                if (StringUtils.isNotEmpty(shipToAddress.getLine3())) {
631                    noteBuffer.append(shipToAddress.getLine3() + "\n");
632                }
633
634                noteBuffer.append(shipToAddress.getCityName() + ", " + shipToAddress.getStateCode() + " " + shipToAddress.getPostalCode() + "\n");
635                noteBuffer.append(shipToAddress.getCountryName());
636            }
637
638        } else {
639
640            if (StringUtils.isNotEmpty(rejectDocument.getInvoiceShipToAddressName())) {
641                noteBuffer.append(rejectDocument.getInvoiceShipToAddressName() + "\n");
642            }
643
644            noteBuffer.append(rejectDocument.getInvoiceShipToAddressLine1() + "\n");
645
646            if (StringUtils.isNotEmpty(rejectDocument.getInvoiceShipToAddressLine2())) {
647                noteBuffer.append(rejectDocument.getInvoiceShipToAddressLine2() + "\n");
648            }
649
650            if (StringUtils.isNotEmpty(rejectDocument.getInvoiceShipToAddressLine3())) {
651                noteBuffer.append(rejectDocument.getInvoiceShipToAddressLine3() + "\n");
652            }
653
654            noteBuffer.append(rejectDocument.getInvoiceShipToAddressCityName() + ", " + rejectDocument.getInvoiceShipToAddressStateCode() + " " + rejectDocument.getInvoiceShipToAddressPostalCode() + "\n");
655            noteBuffer.append(rejectDocument.getInvoiceShipToAddressCountryName());
656
657        }
658        return noteBuffer.toString();
659    }
660
661    public String getInvoiceBillToAddressAsString() {
662
663        StringBuffer noteBuffer = new StringBuffer();
664        noteBuffer.append("Billing Address from Electronic Invoice:\n\n");
665
666        if (!isRejectDocumentHolder()) {
667
668            ElectronicInvoicePostalAddress billToAddress = eInvoice.getCxmlPostalAddress(invoiceOrder,
669                    PurapConstants.ElectronicInvoice.CXML_ADDRESS_BILL_TO_ROLE_ID,
670                    PurapConstants.ElectronicInvoice.CXML_ADDRESS_BILL_TO_NAME);
671
672            if (billToAddress != null) {
673
674                if (StringUtils.isNotEmpty(billToAddress.getName())) {
675                    noteBuffer.append(billToAddress.getName() + "\n");
676                }
677
678                noteBuffer.append(billToAddress.getLine1() + "\n");
679
680                if (StringUtils.isNotEmpty(billToAddress.getLine2())) {
681                    noteBuffer.append(billToAddress.getLine2() + "\n");
682                }
683
684                if (StringUtils.isNotEmpty(billToAddress.getLine3())) {
685                    noteBuffer.append(billToAddress.getLine3() + "\n");
686                }
687
688                noteBuffer.append(billToAddress.getCityName() + ", " + billToAddress.getStateCode() + " " + billToAddress.getPostalCode() + "\n");
689                noteBuffer.append(billToAddress.getCountryName());
690            }
691        } else {
692
693            if (StringUtils.isNotEmpty(rejectDocument.getInvoiceBillToAddressName())) {
694                noteBuffer.append(rejectDocument.getInvoiceBillToAddressName() + "\n");
695            }
696
697            noteBuffer.append(rejectDocument.getInvoiceBillToAddressLine1() + "\n");
698
699            if (StringUtils.isNotEmpty(rejectDocument.getInvoiceBillToAddressLine2())) {
700                noteBuffer.append(rejectDocument.getInvoiceBillToAddressLine2() + "\n");
701            }
702
703            if (StringUtils.isNotEmpty(rejectDocument.getInvoiceBillToAddressLine3())) {
704                noteBuffer.append(rejectDocument.getInvoiceBillToAddressLine3() + "\n");
705            }
706
707            noteBuffer.append(rejectDocument.getInvoiceBillToAddressCityName() + ", " + rejectDocument.getInvoiceBillToAddressStateCode() + " " + rejectDocument.getInvoiceBillToAddressPostalCode() + "\n");
708            noteBuffer.append(rejectDocument.getInvoiceBillToAddressCountryName());
709        }
710
711        return noteBuffer.toString();
712    }
713
714    public Integer getAccountsPayablePurchasingDocumentLinkIdentifier() {
715        if (isRejectDocumentHolder()) {
716            return rejectDocument.getAccountsPayablePurchasingDocumentLinkIdentifier();
717        } else {
718            if (poDocument != null) {
719                return poDocument.getAccountsPayablePurchasingDocumentLinkIdentifier();
720            } else {
721                return null;
722            }
723        }
724    }
725
726    protected class FieldErrorHelper {
727
728        private String fieldName;
729        private String applicationResourceKeyName;
730        private String rejectReasonTypeCode;
731
732        FieldErrorHelper(String fieldName,
733                         String applicationResourceKeyName,
734                         String rejectReasonTypeCode) {
735
736            if (StringUtils.isEmpty(fieldName) ||
737                    StringUtils.isEmpty(applicationResourceKeyName) ||
738                    StringUtils.isEmpty(rejectReasonTypeCode)) {
739                throw new NullPointerException("Invalid field Values [fieldName=" + fieldName + ",applicationResourceKeyName=" + applicationResourceKeyName + ",rejectReasonTypeCode=" + rejectReasonTypeCode + "]");
740            }
741
742            this.fieldName = fieldName;
743            this.applicationResourceKeyName = applicationResourceKeyName;
744            this.rejectReasonTypeCode = rejectReasonTypeCode;
745        }
746
747        public String getApplicationResourceKeyName() {
748            return applicationResourceKeyName;
749        }
750
751        public void setApplicationResourceKeyName(String applicationResourceKeyName) {
752            this.applicationResourceKeyName = applicationResourceKeyName;
753        }
754
755        public String getFieldName() {
756            return fieldName;
757        }
758
759        public void setFieldName(String fieldName) {
760            this.fieldName = fieldName;
761        }
762
763        public String getRejectReasonTypeCode() {
764            return rejectReasonTypeCode;
765        }
766
767        public void setRejectReasonTypeCode(String rejectReasonTypeCode) {
768            this.rejectReasonTypeCode = rejectReasonTypeCode;
769        }
770
771        public String toString() {
772            ToStringBuilder toString = new ToStringBuilder(this);
773            toString.append("fieldName", fieldName);
774            toString.append("applicationResourceKeyName", applicationResourceKeyName);
775            toString.append("rejectReasonTypeCode", rejectReasonTypeCode);
776            return toString.toString();
777        }
778
779    }
780
781
782}