package com.gpc.service; import java.math.BigDecimal; import javax.annotation.Resource; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import javax.jws.soap.SOAPBinding.Style; import javax.servlet.ServletContext; import javax.xml.ws.BindingType; import javax.xml.ws.WebServiceContext; import javax.xml.ws.handler.MessageContext; import com.gpc.manager.*; import com.gpc.tams.json.*; import com.gpc.tams.repository.ipc.IpcTransactionLog; import com.gpc.tams.repository.salesactivities.InvoicingProfile2; import com.gpc.tams.repository.salesactivities.InvoicingProfileDAO2; import com.gpc.tams.util.PasClient; import org.codehaus.jackson.map.ObjectMapper; import org.jboss.ws.annotation.EndpointConfig; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import com.gpc.dto.CheckPaymentDeviceResponseDetail; import com.gpc.dto.RefundResponseDetail; import com.gpc.dto.SaleResponseDetail; import com.gpc.tams.util.ExecutionContext; import com.gpc.dto.BalanceInquiryResponseDetail; import com.gpc.dto.CommonResponseDetail; //http://localhost:8080/IntegratedPaymentCard/webservices/IntegratedPaymentCardService?wsdl @WebService() @EndpointConfig(configName = "Standard SOAP 1.2 WSAddressing Endpoint") @BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_MTOM_BINDING) @SOAPBinding(style = Style.RPC) public class IntegratedPaymentCardService { @Resource private WebServiceContext wsContext; private WebApplicationContext springContext; private static final String NO_IMPLEMENTATION = "There is no implementation for the NAPA Payment - "; private PasClient client; private static final ObjectMapper mapper = new ObjectMapper(); @WebMethod(operationName = "checkPaymentDeviceConnection") @WebResult(name = "checkPaymentDeviceResponse" ) public CheckPaymentDeviceResponseDetail checkPaymentDeviceConnection( @WebParam(name = "journalKey") String journalKey, @WebParam(name = "location") int location, @WebParam(name = "storeNumber") int storeNumber, @WebParam(name = "terminalNumber") int terminalNumber, @WebParam(name = "employeeId") int employeeId, @WebParam(name = "heartBeatCheck") String isHeartBeatCheck) { final ExecutionContext context = getExecutionContext(); context.pushProperty( "JOURNAL_KEY", journalKey ); context.pushProperty( "TERMINAL_NUM", Integer.toString( terminalNumber ) ); context.logTrace( "Web-service endpoint: checkPaymentDeviceConnection" ); CheckPaymentDeviceResponseDetail detail = new CheckPaymentDeviceResponseDetail(); IpcTransactionLog txLog = null; try { if (!useNapaPayment(location)) { final CheckPaymentDeviceConnectionManager checkDevConMgr = getSpringContext().getBean(CheckPaymentDeviceConnectionManager.class); if (isHeartBeatCheck != null && isHeartBeatCheck.equalsIgnoreCase("Y")) { //Added for IPC Device Status Monitoring detail = checkDevConMgr.processMonitoringTransaction(journalKey, location, storeNumber, terminalNumber); } else { detail = checkDevConMgr.processTransaction(journalKey, location, storeNumber, terminalNumber, employeeId); } } else { final PasCheckPaymentDeviceConnectionManager pasMgr = getSpringContext().getBean(PasCheckPaymentDeviceConnectionManager.class); detail = pasMgr.processTransaction(journalKey, location, storeNumber, terminalNumber, employeeId); } } finally { context.clearProperties(); } return detail; } @WebMethod(operationName = "sale") @WebResult(name = "saleResponse") public SaleResponseDetail sale( @WebParam(name = "journalKey") String journalKey, @WebParam(name = "location") int location, @WebParam(name = "storeNumber") int storeNumber, @WebParam(name = "terminalNumber") int terminalNumber, @WebParam(name = "employeeId") int employeeId, @WebParam(name = "amount") BigDecimal amount, @WebParam(name = "bypassSwipe" ) boolean bypassSwipe, @WebParam(name = "cardNotPresent" ) boolean cardNotPresent, @WebParam(name = "disallowedTenderTypes") Integer[] disallowedTenderTypes, @WebParam(name = "invoiceHasNapaGftCardSaleItem") boolean invoiceHasNapaGftCardSaleItem) { final ExecutionContext context = getExecutionContext(); context.pushProperty( "JOURNAL_KEY", journalKey ); context.pushProperty( "TERMINAL_NUM", Integer.toString( terminalNumber ) ); context.logTrace( "Web-service endpoint: sale" ); SaleResponseDetail detail = new SaleResponseDetail(); try { if (!useNapaPayment(location)) { final SaleManager saleMgr = getSpringContext().getBean( SaleManager.class ); detail = saleMgr.processTransaction( journalKey, location, storeNumber, terminalNumber, employeeId, amount, bypassSwipe, disallowedTenderTypes, cardNotPresent, invoiceHasNapaGftCardSaleItem); } else { final PasSaleManager saleMgr = (PasSaleManager)getSpringContext().getBean("pasSaleManager"); detail = saleMgr.processTransaction( journalKey, location, storeNumber, terminalNumber, employeeId, amount, bypassSwipe, disallowedTenderTypes); } } catch (Exception e) { context.getDevLogger().error("sale failed", e); detail.setStatusCode(-1); detail.setResponseMessage(e.getMessage()); } finally { context.clearProperties(); } return detail; } @WebMethod(operationName = "reverseSale") @WebResult(name = "reverseSaleResponse" ) public CommonResponseDetail reverseSale( @WebParam(name = "journalKey") String journalKey, @WebParam(name = "location") int location, @WebParam(name = "storeNumber") int storeNumber, @WebParam(name = "terminalNumber") int terminalNumber, @WebParam(name = "employeeId") int employeeId ) { final ExecutionContext context = getExecutionContext(); context.pushProperty( "JOURNAL_KEY", journalKey ); context.pushProperty( "TERMINAL_NUM", Integer.toString( terminalNumber ) ); context.logTrace( "Web-service endpoint: reverseSale" ); try { if (!useNapaPayment(location)) { final ReverseSaleManager reverseSaleMgr = getSpringContext().getBean( ReverseSaleManager.class ); return reverseSaleMgr.processTransaction( journalKey, location, storeNumber, terminalNumber, employeeId ); } else { CommonResponseDetail detail = new CommonResponseDetail(); // detail.setConnected(false); detail.setResponseMessage(NO_IMPLEMENTATION + "reverse transaction"); return detail; } } finally { context.clearProperties(); } } @WebMethod(operationName = "voidSale") @WebResult(name = "voidSaleResponse" ) public CommonResponseDetail voidSale( @WebParam(name = "journalKey") String journalKey, @WebParam(name = "location") int location, @WebParam(name = "storeNumber") int storeNumber, @WebParam(name = "terminalNumber") int terminalNumber, @WebParam(name = "employeeId") int employeeId ) { final ExecutionContext context = getExecutionContext(); context.pushProperty( "JOURNAL_KEY", journalKey ); context.pushProperty( "TERMINAL_NUM", Integer.toString( terminalNumber ) ); context.logTrace( "Web-service endpoint: voidSale" ); try { if (useNapaPayment(location)) { final PASReversalSaleManager voidSaleMgr = getSpringContext().getBean(PASReversalSaleManager.class); voidSaleMgr.setClient(client); return voidSaleMgr.processTransaction(journalKey, location, storeNumber, terminalNumber, employeeId); } else { final VoidSaleManager voidSaleMgr = getSpringContext().getBean(VoidSaleManager.class); return voidSaleMgr.processTransaction(journalKey, location, storeNumber, terminalNumber, employeeId); } } finally { context.clearProperties(); } } @WebMethod(operationName = "offlineSale") @WebResult(name = "offlineSaleResponse") public CommonResponseDetail offlineSale( @WebParam(name = "journalKey") String journalKey, @WebParam(name = "location") int location, @WebParam(name = "storeNumber") int storeNumber, @WebParam(name = "terminalNumber") int terminalNumber, @WebParam(name = "employeeId") int employeeId, @WebParam(name = "amount") BigDecimal amount, @WebParam(name = "authorizationCode" ) String authorizationCode ) { final ExecutionContext context = getExecutionContext(); context.pushProperty( "JOURNAL_KEY", journalKey ); context.pushProperty( "TERMINAL_NUM", Integer.toString( terminalNumber ) ); context.logTrace( "Web-service endpoint: offlineSale" ); try { final OfflineSaleManager offlineSaleMgr = getSpringContext().getBean( OfflineSaleManager.class ); return offlineSaleMgr.processTransaction( journalKey, location, storeNumber, terminalNumber, employeeId, amount, authorizationCode ); } finally { context.clearProperties(); } } @WebMethod(operationName = "balanceInquiry") @WebResult(name = "balanceInquiryResponse" ) public BalanceInquiryResponseDetail balanceInquiry( @WebParam(name = "journalKey") String journalKey, @WebParam(name = "location") int location, @WebParam(name = "storeNumber") int storeNumber, @WebParam(name = "terminalNumber") int terminalNumber, @WebParam(name = "employeeId") int employeeId) { final ExecutionContext context = getExecutionContext(); context.pushProperty( "JOURNAL_KEY", journalKey ); context.pushProperty( "TERMINAL_NUM", Integer.toString( terminalNumber ) ); context.logTrace( "Web-service endpoint: balanceInquiry" ); try { final BalanceInquiryManager balanceInquiryMgr = getSpringContext().getBean( BalanceInquiryManager.class ); return balanceInquiryMgr.processTransaction( journalKey, location, storeNumber, terminalNumber, employeeId); } finally { context.clearProperties(); } } @WebMethod(operationName = "refund") @WebResult(name = "refundResponse" ) public RefundResponseDetail refund( @WebParam(name = "journalKey") String journalKey, @WebParam(name = "location") int location, @WebParam(name = "storeNumber") int storeNumber, @WebParam(name = "terminalNumber") int terminalNumber, @WebParam(name = "employeeId") int employeeId, @WebParam(name = "amount") BigDecimal amount, @WebParam(name = "bypassSwipe" ) boolean bypassSwipe, @WebParam(name = "cardNotPresent" ) boolean cardNotPresent, @WebParam(name = "disallowedTenderTypes") Integer[] disallowedTenderTypes) { final ExecutionContext context = getExecutionContext(); context.pushProperty( "JOURNAL_KEY", journalKey ); context.pushProperty( "TERMINAL_NUM", Integer.toString( terminalNumber ) ); context.logTrace( "Web-service endpoint: refund" ); SaleResponseDetail detail = new SaleResponseDetail(); try { if (!useNapaPayment(location)) { final RefundManager refundMgr = getSpringContext().getBean(RefundManager.class ); return refundMgr.processTransaction( journalKey, location, storeNumber, terminalNumber, employeeId, amount, bypassSwipe, cardNotPresent, disallowedTenderTypes); } else { final PasRefundManager refundMgr = (PasRefundManager)getSpringContext().getBean("pasRefundManager"); return refundMgr.processTransaction( journalKey, location, storeNumber, terminalNumber, employeeId, amount, bypassSwipe, disallowedTenderTypes, null); } } finally { context.clearProperties(); } } @WebMethod(operationName = "activateAndFundGiftCard") @WebResult(name = "saleResponse") public SaleResponseDetail activateAndFundGiftCard( @WebParam(name = "journalKey") String journalKey, @WebParam(name = "location") int location, @WebParam(name = "storeNumber") int storeNumber, @WebParam(name = "terminalNumber") int terminalNumber, @WebParam(name = "employeeId") int employeeId, @WebParam(name = "amount") BigDecimal amount, @WebParam(name = "activate") boolean activate, @WebParam(name = "merchandiseReturn") boolean merchandiseReturn) { final ExecutionContext context = getExecutionContext(); context.pushProperty( "JOURNAL_KEY", journalKey ); context.pushProperty( "TERMINAL_NUM", Integer.toString( terminalNumber ) ); context.logTrace( "Web-service endpoint: activateAndFundGiftCard : activate: %s, merchandiseReturn: %s", activate, merchandiseReturn ); try { final SaleOfGiftCardManager giftCardSaleMgr = getSpringContext().getBean( SaleOfGiftCardManager.class ); return giftCardSaleMgr.processTransaction( journalKey, location, storeNumber, terminalNumber, employeeId, amount, activate, merchandiseReturn ); } finally { context.clearProperties(); } } @WebMethod(operationName = "loadOfGiftCard") @WebResult(name = "saleResponse") public SaleResponseDetail loadOfGiftCard( @WebParam(name = "journalKey") String journalKey, @WebParam(name = "location") int location, @WebParam(name = "storeNumber") int storeNumber, @WebParam(name = "terminalNumber") int terminalNumber, @WebParam(name = "employeeId") int employeeId, @WebParam(name = "amount") BigDecimal amount, @WebParam(name = "swipeCard") boolean swipeCard ) { final ExecutionContext context = getExecutionContext(); context.pushProperty( "JOURNAL_KEY", journalKey ); context.pushProperty( "TERMINAL_NUM", Integer.toString( terminalNumber ) ); context.logTrace( "Web-service endpoint: loadOfGiftCard" ); try { final LoadOfGiftCardManager giftCardLoadMgr = getSpringContext().getBean( LoadOfGiftCardManager.class ); return giftCardLoadMgr.processTransaction( journalKey, location, storeNumber, terminalNumber, employeeId, amount,swipeCard); } finally { context.clearProperties(); } } @WebMethod(operationName = "voidGiftCardActivation") @WebResult(name = "saleResponse") public SaleResponseDetail voidGiftCardActivation( @WebParam(name = "journalKey") String journalKey, @WebParam(name = "location") int location, @WebParam(name = "storeNumber") int storeNumber, @WebParam(name = "terminalNumber") int terminalNumber, @WebParam(name = "employeeId") int employeeId ) { final ExecutionContext context = getExecutionContext(); context.pushProperty( "JOURNAL_KEY", journalKey ); context.pushProperty( "TERMINAL_NUM", Integer.toString( terminalNumber ) ); context.logTrace( "Web-service endpoint: voidGiftCardActivation" ); try { final VoidOfGiftCardManager giftCardVoidMgr = getSpringContext().getBean( VoidOfGiftCardManager.class ); return giftCardVoidMgr.processTransaction( journalKey, location, storeNumber, terminalNumber, employeeId ); } finally { context.clearProperties(); } } @WebMethod(operationName = "returnGftItem") @WebResult(name = "saleResponse") public SaleResponseDetail returnGftItem( @WebParam(name = "journalKey") String journalKey, @WebParam(name = "location") int location, @WebParam(name = "storeNumber") int storeNumber, @WebParam(name = "terminalNumber") int terminalNumber, @WebParam(name = "employeeId") int employeeId, @WebParam(name = "amount") BigDecimal amount, @WebParam(name = "disallowedTenderTypes") Integer[] disallowedTenderTypes ) { final ExecutionContext context = getExecutionContext(); context.pushProperty( "JOURNAL_KEY", journalKey ); context.pushProperty( "TERMINAL_NUM", Integer.toString( terminalNumber ) ); context.logTrace( "Web-service endpoint: returnGftItem" ); try { final SaleManager saleMgr = getSpringContext().getBean( SaleManager.class ); return saleMgr.processTransaction( journalKey, location, storeNumber, terminalNumber, employeeId, amount, false, disallowedTenderTypes, false, false ); } finally { context.clearProperties(); } } @WebMethod(operationName = "registerWithPaymentSwitch") @WebResult(name = "registerWithPaymentSwitchResponse" ) public CommonResponseDetail registerWithPaymentSwitch( @WebParam(name = "terminalNumber") int terminalNumber ) { final ExecutionContext context = getExecutionContext(); context.pushProperty( "TERMINAL_NUM", Integer.toString( terminalNumber ) ); context.logTrace( "Web-service endpoint: registerWithPaymentSwitch" ); final CommonResponseDetail response = new CommonResponseDetail(); response.setTerminalNumber( terminalNumber ); try { final SettlementService settlementService = getSpringContext().getBean( SettlementService.class ); settlementService.registerWithPaymentSwitch(); response.setStatusCode( 1 ); response.setResponseMessage( "Success" ); } catch (Exception ex) { response.setStatusCode( -1 ); response.setResponseMessage( ex.getMessage() ); context.logError( ex, "Failed to register with payment switch" ); } finally { context.clearProperties(); } return response; } @WebMethod(operationName = "unregisterWithPaymentSwitch") @WebResult(name = "unregisterWithPaymentSwitchResponse" ) public CommonResponseDetail unregisterWithPaymentSwitch( @WebParam(name = "terminalNumber") int terminalNumber ) { final ExecutionContext context = getExecutionContext(); context.pushProperty( "TERMINAL_NUM", Integer.toString( terminalNumber ) ); context.logTrace( "Web-service endpoint: unregisterWithPaymentSwitch" ); final CommonResponseDetail response = new CommonResponseDetail(); response.setTerminalNumber( terminalNumber ); try { final SettlementService settlementService = getSpringContext().getBean( SettlementService.class ); settlementService.transmitSettlementFile(); settlementService.unregisterWithPaymentSwitch(); response.setStatusCode( 1 ); response.setResponseMessage( "Success" ); } catch (Exception ex) { response.setStatusCode( -1 ); response.setResponseMessage( ex.getMessage() ); context.logError( ex, "Failed to unregister with payment switch" ); } finally { context.clearProperties(); } return response; } @WebMethod(operationName = "recordSettlementEntry") @WebResult(name = "recordSettlementEntryResponse" ) public CommonResponseDetail recordSettlementEntry( @WebParam(name = "invoiceId") int invoiceId, @WebParam(name = "terminalNumber") int terminalNumber ) { final ExecutionContext context = getExecutionContext(); context.pushProperty( "INVOICE_ID", Integer.toString( invoiceId ) ); context.pushProperty( "TERMINAL_NUM", Integer.toString( terminalNumber ) ); context.logTrace( "Web-service endpoint: recordSettlementEntry" ); final CommonResponseDetail response = new CommonResponseDetail(); response.setTerminalNumber( terminalNumber ); try { final SettlementService settlementService = getSpringContext().getBean( SettlementService.class ); settlementService.recordSettlementEntry( invoiceId ); response.setStatusCode( 1 ); response.setResponseMessage( "Success" ); } catch (Exception ex) { response.setStatusCode( -1 ); response.setResponseMessage( ex.getMessage() ); context.logError( ex, "Failed to record entry into settlement-trigger file" ); } finally { context.clearProperties(); } return response; } /** * @param terminalNumber payment device used by terminal. * @return true if transmission successful. */ @WebMethod(operationName = "transmitSettlementFile") @WebResult(name = "transmitSettlementFileResponse" ) public CommonResponseDetail transmitSettlementFile(@WebParam(name = "terminalNumber") int terminalNumber ) { final ExecutionContext context = getExecutionContext(); context.pushProperty( "TERMINAL_NUM", Integer.toString(terminalNumber)); context.logTrace( "Web-service endpoint: transmitSettlementFile" ); final CommonResponseDetail response = new CommonResponseDetail(); response.setTerminalNumber(terminalNumber); try { final SettlementTransmissionSender settlementTransmissionSender = getSpringContext().getBean( SettlementTransmissionSender.class ); settlementTransmissionSender.transmitSettlementFile(); response.setStatusCode(1); response.setResponseMessage("Success"); } catch (Exception exception) { response.setStatusCode(-1); response.setResponseMessage(exception.getMessage()); context.logError( exception, "Failed to send settlement-trigger file" ); } finally { context.clearProperties(); } return response; } @WebMethod(operationName = "voidSettlementEntry") public void voidSettlementEntry( @WebParam(name = "journalKey") String journalKey, @WebParam(name = "terminalNumber") int terminalNumber ) { final ExecutionContext context = getExecutionContext(); context.pushProperty( "JOURNAL_KEY", journalKey ); context.pushProperty( "TERMINAL_NUM", Integer.toString( terminalNumber ) ); context.logTrace( "Web-service endpoint: voidSettlementEntry" ); try { final SettlementService settlementService = getSpringContext().getBean( SettlementService.class ); settlementService.voidSettlementEntry( journalKey ); } catch (Exception ex) { context.logError( ex, "Failed to record void entry for settlement-trigger file" ); } finally { context.clearProperties(); } } @WebMethod(operationName = "emboldenSignature") public void emboldenSignature( @WebParam(name = "originalSignatureFile") String originalSignatureFile, @WebParam(name = "emboldenedSignatureFile") String emboldenedSignatureFile ) { final ExecutionContext context = getExecutionContext(); context.logTrace( "Web-service endpoint: emboldenSignature" ); try { final SignatureFileService signatureFileService = getSpringContext().getBean( SignatureFileService.class ); signatureFileService.emboldenSignatureFile( originalSignatureFile, emboldenedSignatureFile ); } catch (Exception ex) { context.logError( ex, "Failed to embolden signature file" ); } finally { context.clearProperties(); } } private synchronized WebApplicationContext getSpringContext() { if (springContext == null) { final ServletContext servletContext = (ServletContext) wsContext.getMessageContext().get( MessageContext.SERVLET_CONTEXT ); springContext = WebApplicationContextUtils.getRequiredWebApplicationContext( servletContext ); } return springContext; } private synchronized ExecutionContext getExecutionContext() { final ExecutionContext context = getSpringContext().getBean( ExecutionContext.class ); if (context.getContextData() == null) { context.setContextData( new IPC_Context() ); } if (client == null) { client = getSpringContext().getBean( PasClient.class ); client.setLogger(context.getDevLogger()); } return context; } private boolean useNapaPayment(int location) { InvoicingProfileDAO2 ipDAO = getSpringContext().getBean( InvoicingProfileDAO2.class ); final InvoicingProfile2 ip = ipDAO.find(location); return ip.isUseNapaPaymentsIPC(); } @WebMethod(operationName = "signatureCapture") @WebResult(name = "saleResponse") public SaleResponseDetail signatureCapture(@WebParam(name = "journalKey") String journalKey, @WebParam(name = "location") int location, @WebParam(name = "storeNumber") int storeNumber, @WebParam(name = "terminalNumber") int terminalNumber, @WebParam(name = "employeeId") int employeeId, @WebParam(name = "amount") BigDecimal amount) { final ExecutionContext context = getExecutionContext(); context.pushProperty("JOURNAL_KEY", journalKey); context.pushProperty("TERMINAL_NUM", Integer.toString(terminalNumber)); context.logDebug("Web-service endpoint: signatureCapture"); try { final SignatureCaptureManager signatureCaptureMgr = getSpringContext() .getBean(SignatureCaptureManager.class); return signatureCaptureMgr.processTransaction(journalKey, location, storeNumber, terminalNumber, employeeId, amount); } finally { context.clearProperties(); } } }