Search in sources :

Example 1 with ProcurementCardTransaction

use of org.kuali.kfs.fp.businessobject.ProcurementCardTransaction in project cu-kfs by CU-CommunityApps.

the class ProcurementCardFlatInputFileType method parse.

public Object parse(byte[] fileByteContent) throws ParseException {
    BufferedReader bufferedFileReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(fileByteContent)));
    String fileLine;
    defaultChart = parameterService.getParameterValueAsString(KfsParameterConstants.FINANCIAL_SYSTEM_DOCUMENT.class, CUKFSParameterKeyConstants.DEFAULT_CHART_CODE);
    errorMessages = new ArrayList<String>();
    ArrayList<ProcurementCardTransaction> transactions = new ArrayList<ProcurementCardTransaction>();
    LOG.info("Beginning parse of file");
    try {
        initialize();
        while ((fileLine = bufferedFileReader.readLine()) != null) {
            ProcurementCardTransaction theTransaction = generateProcurementCardTransaction(fileLine);
            if (theTransaction != null) {
                if (ObjectUtils.isNotNull(theTransaction.getExtension())) {
                    lineCount = ((ProcurementCardTransactionExtendedAttribute) theTransaction.getExtension()).addAddendumLines(bufferedFileReader, lineCount);
                }
                transactions.add(theTransaction);
            }
            lineCount++;
        }
        if (totalDebits.compareTo(fileFooterDebits.abs()) != 0) {
            StringBuffer sb = new StringBuffer();
            sb.append("The sum of all debits does not match the value given in the file footer.");
            sb.append(" Sum of debits generated during ingestion of PCard file: ");
            sb.append(totalDebits);
            sb.append(" Total of debits given in file footer: ");
            sb.append(fileFooterDebits);
            throw new Exception(sb.toString());
        }
        if (totalCredits.compareTo(fileFooterCredits.abs()) != 0) {
            StringBuffer sb = new StringBuffer();
            sb.append("The sum of all credits does not match the value given in the file footer.");
            sb.append(" Sum of credits generated during ingestion of PCard file: ");
            sb.append(totalCredits);
            sb.append(" Total of credits given in file footer: ");
            sb.append(fileFooterCredits);
            throw new Exception(sb.toString());
        }
        if ((headerTransactionCount != footerTransactionCount) || (headerTransactionCount != transactionCount) || (footerTransactionCount != transactionCount)) {
            StringBuffer sb = new StringBuffer();
            sb.append("There is a discrepancy between the number of transactions counted during the ingestion process.");
            sb.append(" Transactions in header: ");
            sb.append(headerTransactionCount);
            sb.append(" Transactions in footer: ");
            sb.append(footerTransactionCount);
            sb.append(" Transactions counted while parsing file: ");
            sb.append(transactionCount);
            throw new Exception(sb.toString());
        }
    } catch (IOException e) {
        LOG.error("Error encountered reading from file content", e);
        throw new ParseException("Error encountered reading from file content", e);
    } catch (Exception e) {
        e.printStackTrace();
        errorMessages.add(e.getMessage());
        errorMessages.add("\r\n");
        errorMessages.add("Parsing of file stopped on line " + lineCount);
        procurementCardErrorEmailService.sendErrorEmail(errorMessages);
        throw new ParseException(e.getMessage());
    }
    return transactions;
}
Also used : InputStreamReader(java.io.InputStreamReader) ArrayList(java.util.ArrayList) IOException(java.io.IOException) IOException(java.io.IOException) ParseException(org.kuali.kfs.sys.exception.ParseException) ProcurementCardTransaction(org.kuali.kfs.fp.businessobject.ProcurementCardTransaction) ByteArrayInputStream(java.io.ByteArrayInputStream) BufferedReader(java.io.BufferedReader) ParseException(org.kuali.kfs.sys.exception.ParseException)

Example 2 with ProcurementCardTransaction

use of org.kuali.kfs.fp.businessobject.ProcurementCardTransaction in project cu-kfs by CU-CommunityApps.

the class ProcurementCardCreateDocumentServiceImpl method createProcurementCardDocument.

/**
 * Creates a ProcurementCardDocument from the List of transactions given.
 *
 * @param transactions List of ProcurementCardTransaction objects to be used for creating the document.
 * @return A ProcurementCardDocument populated with the transactions provided.
 */
@SuppressWarnings({ "rawtypes", "deprecation" })
@Override
public ProcurementCardDocument createProcurementCardDocument(List transactions) {
    ProcurementCardDocument pcardDocument = null;
    dataDictionaryService = SpringContext.getBean(DataDictionaryService.class);
    try {
        // get new document from doc service
        pcardDocument = buildNewProcurementCardDocument();
        List<CapitalAssetInformation> capitalAssets = pcardDocument.getCapitalAssetInformation();
        for (CapitalAssetInformation capitalAsset : capitalAssets) {
            if (ObjectUtils.isNotNull(capitalAsset) && ObjectUtils.isNotNull(capitalAsset.getCapitalAssetInformationDetails())) {
                capitalAsset.setDocumentNumber(pcardDocument.getDocumentNumber());
            }
        }
        ProcurementCardTransaction trans = (ProcurementCardTransaction) transactions.get(0);
        String errorText = validateTransaction(trans);
        createCardHolderRecord(pcardDocument, trans);
        // for each transaction, create transaction detail object and then acct lines for the detail
        int transactionLineNumber = 1;
        KualiDecimal documentTotalAmount = KualiDecimal.ZERO;
        ProcurementCardTransaction transaction = null;
        for (Iterator iter = transactions.iterator(); iter.hasNext(); ) {
            /*ProcurementCardTransaction*/
            transaction = (ProcurementCardTransaction) iter.next();
            // create transaction detail record with accounting lines
            errorText += createTransactionDetailRecord(pcardDocument, transaction, transactionLineNumber);
            // update document total
            documentTotalAmount = documentTotalAmount.add(transaction.getFinancialDocumentTotalAmount());
            transactionLineNumber++;
        }
        pcardDocument.getFinancialSystemDocumentHeader().setFinancialDocumentTotalAmount(documentTotalAmount);
        // pcardDocument.getDocumentHeader().setDocumentDescription("SYSTEM Generated");
        transaction = (ProcurementCardTransaction) transactions.get(0);
        String cardHolderName = transaction.getCardHolderName();
        String vendorName = transaction.getVendorName();
        String transactionType = ((ProcurementCardTransactionExtendedAttribute) transaction.getExtension()).getTransactionType();
        if (transactionType != null && StringUtils.isNotBlank(transactionType)) {
            VENDOR_NAME_MAX_LENGTH = 16;
        } else {
            VENDOR_NAME_MAX_LENGTH = 19;
        }
        if (cardHolderName.length() > CARD_HOLDER_MAX_LENGTH && vendorName.length() > VENDOR_NAME_MAX_LENGTH) {
            cardHolderName = cardHolderName.substring(0, CARD_HOLDER_MAX_LENGTH);
            vendorName = vendorName.substring(0, VENDOR_NAME_MAX_LENGTH);
        }
        if (cardHolderName.length() > CARD_HOLDER_MAX_LENGTH && vendorName.length() <= VENDOR_NAME_MAX_LENGTH) {
            Integer endIndice = 0;
            if ((CARD_HOLDER_MAX_LENGTH + (VENDOR_NAME_MAX_LENGTH - vendorName.length())) > cardHolderName.length()) {
                endIndice = cardHolderName.length();
            } else {
                endIndice = CARD_HOLDER_MAX_LENGTH + (VENDOR_NAME_MAX_LENGTH - vendorName.length());
            }
            cardHolderName = cardHolderName.substring(0, endIndice);
        }
        if (vendorName.length() > VENDOR_NAME_MAX_LENGTH && cardHolderName.length() <= CARD_HOLDER_MAX_LENGTH) {
            Integer endIndice = 0;
            if ((VENDOR_NAME_MAX_LENGTH + (CARD_HOLDER_MAX_LENGTH - cardHolderName.length())) > vendorName.length()) {
                endIndice = vendorName.length();
            } else {
                endIndice = VENDOR_NAME_MAX_LENGTH + (CARD_HOLDER_MAX_LENGTH - cardHolderName.length());
            }
            vendorName = vendorName.substring(0, endIndice);
        }
        String creditCardNumber = transaction.getTransactionCreditCardNumber();
        String lastFour = "";
        if (creditCardNumber.length() > CC_LAST_FOUR) {
            lastFour = creditCardNumber.substring(creditCardNumber.length() - CC_LAST_FOUR);
        }
        String docDesc = cardHolderName + "/" + vendorName + "/" + lastFour;
        if (transactionType != null && StringUtils.isNotBlank(transactionType)) {
            docDesc = transactionType + "/" + cardHolderName + "/" + vendorName + "/" + lastFour;
        }
        if (docDesc.length() > MAX_DOC_DESC_LENGTH) {
            docDesc = docDesc.substring(0, MAX_DOC_DESC_LENGTH);
        }
        pcardDocument.getDocumentHeader().setDocumentDescription(docDesc);
        // Remove duplicate messages from errorText
        String[] messages = StringUtils.split(errorText, ".");
        for (int i = 0; i < messages.length; i++) {
            int countMatches = StringUtils.countMatches(errorText, messages[i]) - 1;
            errorText = StringUtils.replace(errorText, messages[i] + ".", "", countMatches);
        }
        // In case errorText is still too long, truncate it and indicate so.
        Integer documentExplanationMaxLength = dataDictionaryService.getAttributeMaxLength(DocumentHeader.class.getName(), KFSPropertyConstants.EXPLANATION);
        if (documentExplanationMaxLength != null && errorText.length() > documentExplanationMaxLength.intValue()) {
            String truncatedMessage = " ... TRUNCATED.";
            errorText = errorText.substring(0, documentExplanationMaxLength - truncatedMessage.length()) + truncatedMessage;
        }
        pcardDocument.getDocumentHeader().setExplanation(errorText);
    } catch (WorkflowException e) {
        LOG.error("Error creating pcdo documents: " + e.getMessage(), e);
        throw new RuntimeException("Error creating pcdo documents: " + e.getMessage(), e);
    }
    return pcardDocument;
}
Also used : CapitalAssetInformation(org.kuali.kfs.fp.businessobject.CapitalAssetInformation) WorkflowException(org.kuali.rice.kew.api.exception.WorkflowException) DocumentHeader(org.kuali.kfs.krad.bo.DocumentHeader) DataDictionaryService(org.kuali.kfs.krad.service.DataDictionaryService) ProcurementCardDocument(org.kuali.kfs.fp.document.ProcurementCardDocument) ProcurementCardTransactionExtendedAttribute(edu.cornell.kfs.fp.businessobject.ProcurementCardTransactionExtendedAttribute) ProcurementCardTransaction(org.kuali.kfs.fp.businessobject.ProcurementCardTransaction) Iterator(java.util.Iterator) KualiDecimal(org.kuali.rice.core.api.util.type.KualiDecimal)

Example 3 with ProcurementCardTransaction

use of org.kuali.kfs.fp.businessobject.ProcurementCardTransaction in project cu-kfs by CU-CommunityApps.

the class ProcurementCardFlatInputFileType method generateProcurementCardTransaction.

/**
 * Parses a line into a ProcurementCardTransaction.
 *
 * The data in the ProcurementCardTransaction comes from USBank record types 02 and 05.
 * Other USBank record types (01, 95, 98) are either skipped or used for validation.
 *
 * @param line The current line
 * @return A completed transaction or null if there are additional lines in the transaction
 * @throws Exception
 */
private ProcurementCardTransaction generateProcurementCardTransaction(String line) throws Exception {
    String recordId = USBankRecordFieldUtils.extractNormalizedString(line, 0, 2);
    if (recordId == null) {
        throw new Exception("Unable to determine record Id necessary in order to parse line " + lineCount);
    }
    if (recordId.equals(FILE_HEADER_RECORD_ID)) {
        // file header record
        headerTransactionCount = Integer.parseInt(USBankRecordFieldUtils.extractNormalizedString(line, 67, 75));
    }
    if (recordId.equals(FILE_TRAILER_RECORD_ID)) {
        // file footer record
        footerTransactionCount = Integer.parseInt(USBankRecordFieldUtils.extractNormalizedString(line, 21, 29));
        fileFooterCredits = fileFooterCredits.add(new KualiDecimal(USBankRecordFieldUtils.extractNormalizedString(line, 44, 59)));
        fileFooterDebits = fileFooterDebits.add(new KualiDecimal(USBankRecordFieldUtils.extractNormalizedString(line, 29, 44)));
        if (totalDebits.compareTo(fileFooterDebits.abs()) != 0) {
            StringBuffer sb = new StringBuffer();
            sb.append("Debits in file footer do not match the sum of debits in transaction.");
            sb.append(USBankRecordFieldUtils.lineCountMessage(lineCount));
            sb.append(" Debit value given in file footer: ");
            sb.append(fileFooterDebits.abs());
            sb.append(" Debit value generated by summing transactions: ");
            sb.append(totalDebits);
            throw new Exception(sb.toString());
        }
        if (totalCredits.compareTo(fileFooterCredits.abs()) != 0) {
            StringBuffer sb = new StringBuffer();
            sb.append("Credits in file footer do not match the sum of credits in transaction.");
            sb.append(USBankRecordFieldUtils.lineCountMessage(lineCount));
            sb.append(" Credit value given in file footer: ");
            sb.append(fileFooterCredits.abs());
            sb.append(" Credit value generated by summing transactions: ");
            sb.append(totalCredits);
            throw new Exception(sb.toString());
        }
    }
    if (recordId.equals(CARDHOLDER_DATA_HEADER_RECORD_ID)) {
        // cardholder header
        parent = buildProcurementCardTransactionObject();
        // req
        parent.setTransactionCreditCardNumber(USBankRecordFieldUtils.extractNormalizedString(line, 2, 18, true, lineCount));
        // req
        parent.setChartOfAccountsCode(defaultChart);
        parent.setTransactionCycleEndDate(USBankRecordFieldUtils.extractCycleDate(line, 294, 296, lineCount));
        // parent.setTransactionCycleStartDate(transactionCycleStartDate); //may not be able to have
        parent.setCardHolderName(USBankRecordFieldUtils.extractNormalizedString(line, 43, 68));
        parent.setCardHolderLine1Address(USBankRecordFieldUtils.extractNormalizedString(line, 68, 104));
        parent.setCardHolderLine2Address(USBankRecordFieldUtils.extractNormalizedString(line, 104, 140));
        parent.setCardHolderCityName(USBankRecordFieldUtils.extractNormalizedString(line, 140, 165));
        parent.setCardHolderStateCode(USBankRecordFieldUtils.extractNormalizedString(line, 165, 167));
        // KITI-2203 : Removing last four characters from zip+4 so validation performs properly.
        parent.setCardHolderZipCode(USBankRecordFieldUtils.extractNormalizedString(line, 167, 172));
        // parent.setCardHolderZipCode(extractNormalizedString(line, 167, 176));
        parent.setCardHolderAlternateName(USBankRecordFieldUtils.extractNormalizedString(line, 191, 206));
        parent.setCardHolderWorkPhoneNumber(USBankRecordFieldUtils.extractNormalizedString(line, 206, 216));
        // parent.setCardLimit(extractDecimal(line, 352, 363));
        parent.setCardStatusCode(USBankRecordFieldUtils.extractNormalizedString(line, 267, 268));
        String companyCode = USBankRecordFieldUtils.extractNormalizedString(line, 252, 257);
        if (companyCode.equals("99998")) {
            duplicateTransactions = true;
        } else {
            duplicateTransactions = false;
        }
    }
    if (recordId.equals(TRANSACTION_INFORMATION_RECORD_ID) && !duplicateTransactions) {
        ProcurementCardTransaction child = buildProcurementCardTransactionObject();
        // Pull everything in from the preceding '05' record
        child.setTransactionCreditCardNumber(parent.getTransactionCreditCardNumber());
        child.setTransactionCycleEndDate(parent.getTransactionCycleEndDate());
        child.setCardHolderName(parent.getCardHolderName());
        child.setCardHolderLine1Address(parent.getCardHolderLine1Address());
        child.setCardHolderLine2Address(parent.getCardHolderLine2Address());
        child.setCardHolderCityName(parent.getCardHolderCityName());
        child.setCardHolderStateCode(parent.getCardHolderStateCode());
        child.setCardHolderZipCode(parent.getCardHolderZipCode());
        child.setCardHolderWorkPhoneNumber(parent.getCardHolderWorkPhoneNumber());
        child.setCardHolderAlternateName(parent.getCardHolderAlternateName());
        // child.setCardLimit(parent.getCardLimit());
        child.setCardStatusCode(parent.getCardStatusCode());
        parseAccountingInformation(line, child);
        child.setProjectCode(USBankRecordFieldUtils.extractNormalizedString(line, 336, 346));
        // req
        child.setFinancialDocumentTotalAmount(USBankRecordFieldUtils.extractDecimal(line, 79, 91, lineCount));
        // req
        child.setTransactionDebitCreditCode(USBankRecordFieldUtils.convertDebitCreditCode(line.substring(64, 65)));
        // req
        child.setTransactionDate(USBankRecordFieldUtils.extractDate(line, 45, 53, lineCount));
        child.setTransactionOriginalCurrencyCode(USBankRecordFieldUtils.extractNormalizedString(line, 61, 64));
        child.setTransactionBillingCurrencyCode(USBankRecordFieldUtils.extractNormalizedString(line, 76, 79));
        child.setVendorName(USBankRecordFieldUtils.extractNormalizedString(line, 95, 120));
        child.setTransactionReferenceNumber(USBankRecordFieldUtils.extractNormalizedString(line, 18, 41));
        child.setTransactionMerchantCategoryCode(USBankRecordFieldUtils.extractNormalizedString(line, 91, 95));
        child.setTransactionPostingDate(USBankRecordFieldUtils.extractDate(line, 53, 61, lineCount));
        child.setTransactionOriginalCurrencyAmount(USBankRecordFieldUtils.extractDecimalWithCents(line, 64, 76, lineCount));
        child.setTransactionCurrencyExchangeRate(USBankRecordFieldUtils.extractDecimal(line, 304, 317, lineCount).bigDecimalValue());
        child.setTransactionSettlementAmount(USBankRecordFieldUtils.extractDecimal(line, 79, 91, lineCount));
        // child.setTransactionTaxExemptIndicator(USBankAddendumRecordFieldUtils.extractNormalizedString(line, 234, 235));
        child.setTransactionPurchaseIdentifierIndicator(USBankRecordFieldUtils.extractNormalizedString(line, 272, 273));
        child.setTransactionPurchaseIdentifierDescription(USBankRecordFieldUtils.extractNormalizedString(line, 273, 298));
        child.setVendorCityName(USBankRecordFieldUtils.extractNormalizedString(line, 120, 146));
        child.setVendorStateCode(USBankRecordFieldUtils.extractNormalizedString(line, 146, 148));
        // child.setVendorZipCode(USBankAddendumRecordFieldUtils.extractNormalizedString(line, 152, 161));
        // 
        // Fix to handle zip codes provided by US Bank
        // 
        String vendorZipCode = USBankRecordFieldUtils.extractNormalizedString(line, 152, 161);
        if (vendorZipCode.startsWith("0000")) {
            vendorZipCode = USBankRecordFieldUtils.extractNormalizedString(line, 156, 161);
        }
        child.setVendorZipCode(vendorZipCode);
        child.setVisaVendorIdentifier(USBankRecordFieldUtils.extractNormalizedString(line, 176, 192));
        if (child.getTransactionDebitCreditCode().equals("D")) {
            accumulatedDebits = accumulatedDebits.add(child.getTransactionSettlementAmount());
        } else {
            accumulatedCredits = accumulatedCredits.add(child.getTransactionSettlementAmount());
        }
        ProcurementCardTransactionExtendedAttribute extension = buildProcurementCardTransactionExtendedAttributeObject();
        extension.setTransactionType(USBankRecordFieldUtils.extractNormalizedString(line, 346, 348));
        if (child.getTransactionSequenceRowNumber() == null) {
            Integer generatedTransactionSequenceRowNumber = SpringContext.getBean(SequenceAccessorService.class).getNextAvailableSequenceNumber(FP_PRCRMNT_CARD_TRN_MT_SEQ).intValue();
            child.setTransactionSequenceRowNumber(generatedTransactionSequenceRowNumber);
            extension.setTransactionSequenceRowNumber(child.getTransactionSequenceRowNumber());
        }
        child.setExtension(extension);
        transactionCount++;
        return child;
    }
    // Still need to update totals and transaction count so validation works properly, but don't want transactions to be loaded
    if (recordId.equals(TRANSACTION_INFORMATION_RECORD_ID) && duplicateTransactions) {
        if (USBankRecordFieldUtils.convertDebitCreditCode(line.substring(64, 65)).equals("D")) {
            accumulatedDebits = accumulatedDebits.add(USBankRecordFieldUtils.extractDecimal(line, 79, 91, lineCount));
        } else {
            accumulatedCredits = accumulatedCredits.add(USBankRecordFieldUtils.extractDecimal(line, 79, 91, lineCount));
        }
        transactionCount++;
    }
    if (recordId.equals(CARDHOLDER_TRAILER_RECORD_ID)) {
        // cardholder footer
        KualiDecimal recordDebits = new KualiDecimal(USBankRecordFieldUtils.extractNormalizedString(line, 24, 36));
        KualiDecimal recordCredits = new KualiDecimal(USBankRecordFieldUtils.extractNormalizedString(line, 36, 48));
        if (accumulatedCredits.compareTo(recordCredits.abs()) != 0) {
            StringBuffer sb = new StringBuffer();
            sb.append("Total credits given in cardholder footer do not sum to same value as transactions.");
            sb.append(USBankRecordFieldUtils.lineCountMessage(lineCount));
            sb.append(" Credit value given in cardholder footer: ");
            sb.append(recordCredits.abs());
            sb.append(" Credit value generated by summing transactions: ");
            sb.append(accumulatedCredits);
            throw new Exception(sb.toString());
        }
        if (accumulatedDebits.compareTo(recordDebits.abs()) != 0) {
            StringBuffer sb = new StringBuffer();
            sb.append("Total debits given in cardholder footer do not sum to same value as transactions.");
            sb.append(USBankRecordFieldUtils.lineCountMessage(lineCount));
            sb.append(" Debit value given in cardholder footer: ");
            sb.append(recordDebits.abs());
            sb.append(" Debit value generated by summing transactions: ");
            sb.append(accumulatedDebits);
            throw new Exception(sb.toString());
        }
        totalCredits = totalCredits.add(accumulatedCredits);
        totalDebits = totalDebits.add(accumulatedDebits);
        accumulatedCredits = new KualiDecimal(0);
        accumulatedDebits = new KualiDecimal(0);
    }
    return null;
}
Also used : ProcurementCardTransaction(org.kuali.kfs.fp.businessobject.ProcurementCardTransaction) KualiDecimal(org.kuali.rice.core.api.util.type.KualiDecimal) IOException(java.io.IOException) ParseException(org.kuali.kfs.sys.exception.ParseException) ProcurementCardTransactionExtendedAttribute(edu.cornell.kfs.fp.businessobject.ProcurementCardTransactionExtendedAttribute)

Aggregations

ProcurementCardTransaction (org.kuali.kfs.fp.businessobject.ProcurementCardTransaction)3 ProcurementCardTransactionExtendedAttribute (edu.cornell.kfs.fp.businessobject.ProcurementCardTransactionExtendedAttribute)2 IOException (java.io.IOException)2 ParseException (org.kuali.kfs.sys.exception.ParseException)2 KualiDecimal (org.kuali.rice.core.api.util.type.KualiDecimal)2 BufferedReader (java.io.BufferedReader)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 InputStreamReader (java.io.InputStreamReader)1 ArrayList (java.util.ArrayList)1 Iterator (java.util.Iterator)1 CapitalAssetInformation (org.kuali.kfs.fp.businessobject.CapitalAssetInformation)1 ProcurementCardDocument (org.kuali.kfs.fp.document.ProcurementCardDocument)1 DocumentHeader (org.kuali.kfs.krad.bo.DocumentHeader)1 DataDictionaryService (org.kuali.kfs.krad.service.DataDictionaryService)1 WorkflowException (org.kuali.rice.kew.api.exception.WorkflowException)1