package com.gpc.manager; import com.gpc.dto.SaleResponseDetail; import com.gpc.message.isd.fields.CardType; import com.gpc.message.isd.fields.StatusCode; import com.gpc.tams.json.*; import com.gpc.tams.repository.ipc.IpcTransactionLog; import com.gpc.tams.repository.ipc.TransactionType; import com.gpc.tams.util.RefTenderType; import com.gpc.tams.util.PasClient; import java.math.BigDecimal; import java.sql.Timestamp; import org.apache.commons.lang.ArrayUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.HttpServerErrorException; @Service("pasSaleManager") public class PasSaleManager extends PasManager { @Autowired private PASReversalSaleManager voidSaleManager; protected String endpoint = PasClient.SALE_ENDPOINT; protected TransactionType transactionType = TransactionType.SALE; public SaleResponseDetail processTransaction( String journalKey, int location, int storeNumber, int terminalNumber, int employeeId, BigDecimal amount, boolean bypassSwipe, Integer[] disallowedRefTenderTypes ) { context.logDebug("journalKey: %s, storeNumber: %s, terminalNumber: %s, amount: %s, bypass: %s, disallowedTenderTypes: %s", journalKey, storeNumber, terminalNumber, amount, bypassSwipe, ArrayUtils.toString(disallowedRefTenderTypes)); SaleResponseDetail response = null; if (storeNumber == 9999) { context.logWarn("Using Mock response instead of normal response"); response = new MockSaleResponseBuilder(amount, bypassSwipe, disallowedRefTenderTypes, journalKey, storeNumber, terminalNumber).generateResponse(); context.logWarn("Mock Response: "+response.toString()); return response; } final IpcTransactionLog txLog = txTracker.startTracking( journalKey, storeNumber, terminalNumber, employeeId, transactionType, amount ); SaleReq saleReq = createSaleReq(journalKey, location, storeNumber, terminalNumber, employeeId, amount); try { String url = getInvoicingProfile(location).getIpcBaseUrl() + endpoint; setStore(saleReq.getStore()); String saleReqStr = mapper.writeValueAsString(saleReq); ResponseEntity entity = client.post(saleReqStr, url, journalKey); SaleResp saleResp = mapper.readValue(entity.getBody(), SaleResp.class); // TODO need to update CardType if PAS has new type CardType brand = CardType.get(saleResp.getCard().getBrand()); RefTenderType refTenderType = brand.getTenderType(); int refTenderTypeId = refTenderType==null?-1:refTenderType.getRefTenderTypeId(); response = new SaleResponseDetail( storeNumber, terminalNumber, journalKey, StatusCode.UNKNOWN_EXCEPTION.getCode(), saleResp.getProcessor().getResponseMessage(), amount, saleResp.getTimestamp(), saleResp.getProcessor().getAuthorizationCode(), String.valueOf(saleResp.getProcessor().getResponseCode()), null, //authMsg.getHostActionCode(), null, //authMsg.getExpirationDate(), null, //authMsg.getCashBack(), // use the account number to determine what type of card this actually is // and make sure its consistent with the tender type. brand, refTenderTypeId, true, null, saleResp.getCard().getLastFour(), //authMsg.getPartialAccountNumber(), null); //authMsg.getCardHolderName() if (saleResp.getStatus().equals(StatusCode.APPROVED.toString())) { // TODO remove this code when disallowedRefTenderTypes is passed to PAS if (PasClient.isDisallowed(refTenderType, disallowedRefTenderTypes)) { response = new SaleResponseDetail(storeNumber, terminalNumber, journalKey, StatusCode.LOOKUP_FAILED.getCode(), "Card Type Not Allowed"); if (refTenderType == null) { context.logWarn("Unknown tender type, using: "+RefTenderType.CASH); response.setRefTenderTypeId(RefTenderType.CASH.getRefTenderTypeId()); } else { response.setRefTenderTypeId(refTenderTypeId); } // TODO add void code } else { TransactionLogHandler.updateTxLogEntry ( txLog, saleResp ); // response = captureSignature(saleResp); response.setStatusCode(StatusCode.APPROVED.getCode()); } } else { response.setStatusCode(StatusCode.DECLINED.getCode()); } } catch (HttpClientErrorException | HttpServerErrorException e) { try { String saleRespStr = e.getResponseBodyAsString(); SaleErrorResp error = mapper.readValue(saleRespStr, SaleErrorResp.class); context.logError(e,"Sale failed:" + error.getCode() + " | " + error.getMessage() + " | " + error.getHelp()); response = new SaleResponseDetail (storeNumber, terminalNumber, journalKey, StatusCode.PAV_UNKNOWN_EXCEPTION.getCode(), error.getMessage()); } catch (Exception ex) { context.logError(e,"Sale failed to parse failed response"); response = new SaleResponseDetail( storeNumber, terminalNumber, journalKey, StatusCode.PAV_UNKNOWN_EXCEPTION.getCode(), e.getLocalizedMessage()); } } catch (Exception e) { context.logError(e,"Sale failed"); response = new SaleResponseDetail( storeNumber, terminalNumber, journalKey, StatusCode.PAV_UNKNOWN_EXCEPTION.getCode(), e.getLocalizedMessage()); } finally { txLog.setItkCallCompleteTime( new Timestamp( System.currentTimeMillis() ) ); txLog.setItkResultStatus( response == null ? StatusCode.UNKNOWN_EXCEPTION.getCode() : response.getStatusCode() ); txTracker.updateTracking( txLog ); } return response; } protected SaleResponseDetail captureSignature(SaleResp saleResp) { // TODO add implementation return null; } private SaleReq createSaleReq(String journalKey, int location, int storeNumber, int terminalNumber, int employeeId, BigDecimal amount) { SaleReq saleReq = new SaleReq(); saleReq.setPinpadId(String.valueOf(terminalNumber)); SaleTransaction transaction = new SaleTransaction(); saleReq.setTransaction(transaction); transaction.setAmount(amount); transaction.setStoreTransactionId(journalKey); transaction.setCurrency(PasClient.CURRENCY_USD); Store store = new Store(); saleReq.setStore(store); store.setNumber(storeNumber); store.setLocation(location); store.setTerminalId(String.valueOf(terminalNumber)); store.setEmployeeId(employeeId); return saleReq; } }