/* * SAVoidTransactionActionImpl * * 07/29/2002 * * Copyright: * Licensed Materials - Property of IBM * "Restricted Materials of IBM" * 5724-AEF * (C) Copyright IBM Corp. 2003. * * %W% %E% */ package com.ibm.retail.AEF.action; import com.ibm.retail.AEF.automation.*; import com.ibm.retail.AEF.util.*; import com.ibm.retail.si.util.*; import com.ibm.retail.si.Copyright; import com.ibm.retail.AEF.factory.*; import com.ibm.retail.AEF.thread.*; import com.ibm.retail.AEF.data.*; import com.ibm.retail.AEF.session.*; import java.util.*; import java.rmi.*; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * SAVoidTransactionActionImpl is a class which the POSAutomationProvider uses to accomplish * voiding the current transaction. * */ public class SAVoidTransactionActionImpl extends SAActionImpl { static String copyright() { return com.ibm.retail.si.Copyright.IBM_COPYRIGHT_SHORT; } private static AEFPerfTrace perfTrace = AEFPerfTrace.getInstance(); /** * Constructor * * @param request The ActionRequest which contains a hashtable of arguments. * @exception AEFException * AEFException error codes: * <br>AEFConst.CONFIG_ERROR, AEFConst.FACTORY_ERROR */ public SAVoidTransactionActionImpl(ActionRequest request) throws AEFException { super(request); if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter and -Exit SAVoidTransactionActionImpl.SAVoidTransactionActionImpl()."); log.trace(tempAEFMessage); } } /** * Tries to void the current transaction and return the application to the ITEMENTRY state * and SELECT_PROCEDURE substate as defined in the configuration files. * * @return Object N/A (null). * @exception AEFException * AEFException error codes: * <br>AEFConst.PROCEDURE_NOT_ALLOWED, AEFConst.TRANSACTION_NOT_ACTIVE * <br>AEFConst.APPLICATION_NOT_IN_PROPER_STATE * <br>AEFConst.MANAGER_OVERRIDE_REQUIRED */ public Object performAction() throws AEFException { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter SAVoidTransactionActionImpl.performAction()."); log.trace(tempAEFMessage); } super.performAction(); // Call super to perform any common processing and clear any errors before we start. boolean salesTranInProgress = false; boolean nonSalesTranInProgress = false; Transaction trans = null; ObjectDetector detector = null; try { // Check for a "partial" transaction which was started, but no items have been sold. trans = automationProvider.getTransaction(); if (trans != null) { if (trans.getTransactionInfo().getTransactionID() == null) { // Clear the partial transaction object. trans.setIsActive(false); detector = ((DetectorAccess)(SessionContext.getSession())).getTransactionDetector(); detector.reset(); automationProvider.setTransaction(null); return null; } } // Check the precondition that we are in the middle of a transaction. salesTranInProgress = getBooleanProviderProperty(WorkstationStatusProperties.CATEGORY, WorkstationStatusProperties.SALES_TRANSACTION_IN_PROGRESS); nonSalesTranInProgress = getBooleanProviderProperty(WorkstationStatusProperties.CATEGORY, WorkstationStatusProperties.NONSALES_TRANSACTION_IN_PROGRESS); if (!salesTranInProgress && !nonSalesTranInProgress) { // Not in the middle of the transaction. String tempString = "SAVoidTransactionActionImpl.performAction(): Cannot void a transaction because no transaction is in progress."; AEFException tempException = new AEFException(AEFConst.PROCEDURE_NOT_ALLOWED, AEFConst.TRANSACTION_NOT_ACTIVE, tempString); tempAEFMessage.setMessage(tempString); log.error(tempAEFMessage, tempException); throw tempException; } // Try to return the application to the "ITEMENTRY" State. // First get all the states and sub-sates from the config files. initializeStates(); initializeSubStates(); // Loop several times through the state test to ensure that we do not miss an escape route. for (int i = 0; i < 2; i++) { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("Start of Loop " + i + ". State = " + getCurrentState() + " Substate = " + getCurrentSubstate() + "."); log.trace(tempAEFMessage); } // If in states signon, password, so pswd, standalone or autosign throw invalid state exception. if (getCurrentState().equalsIgnoreCase(idState) || getCurrentState().equalsIgnoreCase(passwordState) || getCurrentState().equalsIgnoreCase(soPasswordState) || getCurrentState().equalsIgnoreCase(standaloneState) || getCurrentState().equalsIgnoreCase(autoSignState)) { String tempString = "SAVoidTransactionActionImpl.performAction(): POS application not in proper state to void a transaction.\n Application is in state " + getCurrentState() + "."; AEFException tempException = new AEFException(AEFConst.APPLICATION_NOT_IN_PROPER_STATE, 0, tempString); tempAEFMessage.setMessage(tempString); log.error(tempAEFMessage, tempException); throw tempException; } if (getCurrentState().equalsIgnoreCase(acctNoState) || getCurrentState().equalsIgnoreCase(eftAccountState) || getCurrentState().equalsIgnoreCase(eftBlinqState) || getCurrentState().equalsIgnoreCase(eftVoid1State) || getCurrentState().equalsIgnoreCase(eftVoid2State) || getCurrentState().equalsIgnoreCase(micrTransactionState) || getCurrentState().equalsIgnoreCase(micrAccountState) || getCurrentState().equalsIgnoreCase(micrSequenceState)) { String tempString = "SAVoidTransactionActionImpl.performAction(): POS application is in an unexpected state.\n Application is in state " + getCurrentState() + "."; AEFException tempException = new AEFException(AEFConst.APPLICATION_NOT_IN_PROPER_STATE, 0, tempString); tempAEFMessage.setMessage(tempString); log.error(tempAEFMessage, tempException); throw tempException; } // If in spec-so state send <clear> {password} <SO>. if (getCurrentState().equalsIgnoreCase(securedState)) { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("Loop " + i + ". State = " + getCurrentState() + " Substate = " + getCurrentSubstate() + "."); log.trace(tempAEFMessage); } try { sendClearSequence(false); sendSpecsoToOverrideSequence(true); if (getCurrentState().equalsIgnoreCase(securedState)) { String tempString = "SAVoidTransactionActionImpl.performAction(): POS application not in proper state to void a transaction.\n Application is in state " + getCurrentState() + "."; AEFException tempException = new AEFException(AEFConst.APPLICATION_NOT_IN_PROPER_STATE, 0, tempString); tempAEFMessage.setMessage(tempString); log.error(tempAEFMessage, tempException); throw tempException; } } catch (AEFException e) { // Check to see if we timed out. If so log the error but continue, we may be in a state which we can fix below. if (e.getErrorCode() != AEFConst.OPERATION_TIMEOUT) { tempAEFMessage.setMessage("AEF Exception thrown in SAVoidTransactionActionImpl.performAction()."); log.error(tempAEFMessage, e); throw(e); } else { if (log.isDebugEnabled()) { tempAEFMessage.setMessage("SAVoidTransactionActionImp.performAction timeout after sendSpecsoToOverrideSequence()."); log.debug(tempAEFMessage); } } } } // If in override state send <override> {password} <enter> if (getCurrentState().equalsIgnoreCase(overrideState)) { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("Loop " + i + ". State = " + getCurrentState() + " Substate = " + getCurrentSubstate() + "."); log.trace(tempAEFMessage); } try { String autoMgrOverride = automationProvider.getProperty(POSAutomationProvider.AUTO_MGR_OVERRIDE); if (autoMgrOverride.equalsIgnoreCase("true")) { automationProvider.managerOverride(); } else { AEFException ex = new AEFException(AEFConst.MANAGER_OVERRIDE_REQUIRED, 0, "SAVoidTransactionActionImpl.performAction(): A manager override is required for this operation but automatic override is not allowed."); throw ex; } } catch (AEFException e) { // Check to see if we timed out. If so log the error but continue, we may be in a state which we can fix below. if (e.getErrorCode() != AEFConst.OPERATION_TIMEOUT) { tempAEFMessage.setMessage("AEF Exception thrown in SAVoidTransactionActionImpl.performAction()."); log.error(tempAEFMessage, e); throw(e); } else { if (log.isDebugEnabled()) { tempAEFMessage.setMessage("SAVoidTransactionActionImp.performAction timeout after managerOverride()."); log.debug(tempAEFMessage); } } } } // If in states Tender Cashing/Exchange, Cashier Loan/Pickup, Tender Count, or Price Verify/Change then send <clear> <void> <total>. if (getCurrentState().equalsIgnoreCase(tenderCashingExchangeState) || getCurrentState().equalsIgnoreCase(cashierLoanPickupTenderCountState) || getCurrentState().equalsIgnoreCase(priceVerifyState)) { if (log.isTraceEnabled()) { log.trace("* Loop " + i + ". State = " + getCurrentState() + " Substate = " + getCurrentSubstate() + "."); } try { sendClearSequence(false); sendVoidSequence(true); } catch (AEFException e) { // Check to see if we timed out. If so log the error but continue, we may be in a state which we can fix below. if (e.getErrorCode() != AEFConst.OPERATION_TIMEOUT) { tempAEFMessage.setMessage("AEF Exception thrown in SAVoidTransactionActionImpl.performAction()."); log.error(tempAEFMessage, e); throw(e); } else { if (log.isDebugEnabled()) { tempAEFMessage.setMessage("SAVoidTransactionActionImp.performAction timeout after sendVoidSequence()."); log.debug(tempAEFMessage); } } } } // If in state enter, wait to get out of the state . if (getCurrentState().equalsIgnoreCase(enterState)) { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("Loop " + i + ". State = " + getCurrentState() + " Substate = " + getCurrentSubstate() + "."); log.trace(tempAEFMessage); } try { waitForStateChange(enterState); } catch (AEFException e) { // Check to see if we timed out. If so log the error but continue, we may be in a state which we can fix below. if (e.getErrorCode() != AEFConst.OPERATION_TIMEOUT) { tempAEFMessage.setMessage("AEF Exception thrown in SAVoidTransactionActionImpl.performAction()."); log.error(tempAEFMessage, e); throw(e); } else { if (log.isDebugEnabled()) { tempAEFMessage.setMessage("SAVoidTransactionActionImp.performAction timeout after waitForStateChange()."); log.debug(tempAEFMessage); } } } } // If in state clear then call the error handler. if (getCurrentState().equalsIgnoreCase(clearState)) { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("Loop " + i + ". State = " + getCurrentState() + " Substate = " + getCurrentSubstate() + "."); log.trace(tempAEFMessage); } try { handleError(); } catch (AEFException e) { // Check to see if we timed out. If so log the error but continue, we may be in a state which we can fix below. if (e.getErrorCode() != AEFConst.OPERATION_TIMEOUT) { tempAEFMessage.setMessage("AEF Exception thrown in SAVoidTransactionActionImpl.performAction()."); log.error(tempAEFMessage, e); throw(e); } else { if (log.isDebugEnabled()) { tempAEFMessage.setMessage("SAVoidTransactionActionImp.performAction timeout after handleError()."); log.debug(tempAEFMessage); } } } } // If in states Acct/ovr, ent/clr, or ent/dat then send clear sequence. if (getCurrentState().equalsIgnoreCase(acctOvrState) || getCurrentState().equalsIgnoreCase(enterClearState) || getCurrentState().equalsIgnoreCase(enterDataState)) { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("Loop " + i + ". State = " + getCurrentState() + " Substate = " + getCurrentSubstate() + "."); log.trace(tempAEFMessage); } try { sendClearSequence(true); } catch (AEFException e) { // Check to see if we timed out. If so log the error but continue, we may be in a state which we can fix below. if (e.getErrorCode() != AEFConst.OPERATION_TIMEOUT) { tempAEFMessage.setMessage("AEF Exception thrown in SAVoidTransactionActionImpl.performAction()."); log.error(tempAEFMessage, e); throw(e); } else { if (log.isDebugEnabled()) { tempAEFMessage.setMessage("SAVoidTransactionActionImp.performAction timeout after sendClearSequence()."); log.debug(tempAEFMessage); } } } } // If in Terminal Monitor/Transfer state send <Total> <Clear> if (getCurrentState().equalsIgnoreCase(terminalTransferMonitorState)) { if (log.isTraceEnabled()) { tempAEFMessage.setMessage(" Loop " + i + ". State = " + getCurrentState() + " Substate = " + getCurrentSubstate() + "."); log.trace(tempAEFMessage); } try { sendTotalSequence(true); } catch (AEFException e) { // Check to see if we timed out. If so log the error but continue, we may be in a state which we can fix below. if (e.getErrorCode() != AEFConst.OPERATION_TIMEOUT) { tempAEFMessage.setMessage("AEF Exception thrown in SAVoidTransactionActionImpl.performAction()."); log.error(tempAEFMessage, e); throw(e); } else { if (log.isDebugEnabled()) { tempAEFMessage.setMessage("SAVoidTransactionActionImp.performAction timeout after sendTotalSequence()."); log.debug(tempAEFMessage); } } } } // If in Tender Listing state send <clear> 0 <SO> if (getCurrentState().equalsIgnoreCase(tenderListState)) { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("Loop " + i + ". State = " + getCurrentState() + " Substate = " + getCurrentSubstate() + "."); log.trace(tempAEFMessage); } try { sendStartTransactionSequence(true); } catch (AEFException e) { // Check to see if we timed out. If so log the error but continue, we may be in a state which we can fix below. if (e.getErrorCode() != AEFConst.OPERATION_TIMEOUT) { tempAEFMessage.setMessage("AEF Exception thrown in SAVoidTransactionActionImpl.performAction()."); log.error(tempAEFMessage, e); throw(e); } else { if (log.isDebugEnabled()) { tempAEFMessage.setMessage("SAVoidTransactionActionImp.performAction timeout after sendStartTransactionSequence()."); log.debug(tempAEFMessage); } } } } // If in ITEMENTRY state send <Void><Total> if (getCurrentState().equalsIgnoreCase(mainState)) { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("** Loop " + i + ". State = " + getCurrentState() + " Substate = " + getCurrentSubstate() + "."); log.trace(tempAEFMessage); } if (getCurrentState().equalsIgnoreCase(mainState) && getCurrentSubstate().equalsIgnoreCase(mainSubState)) { break; // We are at the desired state. } else { try { sendVoidSequence(); } catch (AEFException e) { // Check to see if we timed out. If so log the error but continue, we may be in a state which we can fix below. if (e.getErrorCode() != AEFConst.OPERATION_TIMEOUT) { tempAEFMessage.setMessage("AEF Exception thrown in SAVoidTransactionActionImpl.performAction()."); log.error(tempAEFMessage, e); throw(e); } else { if (log.isDebugEnabled()) { tempAEFMessage.setMessage("SAVoidTransactionActionImp.performAction timeout after sendVoidSequence()."); log.debug(tempAEFMessage); } } } } } // If in signon state then we did a forced logoff (which voided the transaction) so break from loop. if (getCurrentState().equalsIgnoreCase(idState)) { break; } if (log.isTraceEnabled()) { tempAEFMessage.setMessage("End of Loop " + i + ". State = " + getCurrentState() + " Substate = " + getCurrentSubstate() + "."); log.trace(tempAEFMessage); } } // End of For Loop // If we are out of the loop with an error condition, lets try to clear it one last time. if (getCurrentState().equalsIgnoreCase(clearState)) { try { handleError(); } catch (AEFException e) { // Check to see if we timed out. If so log the error but continue, we may be in a state which we can fix below. if (e.getErrorCode() != AEFConst.OPERATION_TIMEOUT) { tempAEFMessage.setMessage("AEF Exception thrown in SAVoidTransactionActionImpl.performAction()."); log.error(tempAEFMessage, e); throw(e); } else { if (log.isDebugEnabled()) { tempAEFMessage.setMessage("SAVoidTransactionActionImp.performAction timeout after handleError()."); log.debug(tempAEFMessage); } } } } // Get the current sub-state and see if we are in mainstate and substate. if (((!(getCurrentState().equalsIgnoreCase(mainState))) || (!(getCurrentSubstate().equalsIgnoreCase(mainSubState)))) && (!(getCurrentState().equalsIgnoreCase(idState)))) { String tempString = "SAVoidTransactionActionImpl.performAction(): The application is in state " + getCurrentState() + " substate " + getCurrentSubstate() + " but should be in state " + mainState + " substate " + mainSubState + "or in state " + idState + "."; AEFException tempException = new AEFException(AEFConst.APPLICATION_NOT_IN_PROPER_STATE, 0, tempString); tempAEFMessage.setMessage(tempString); log.error(tempAEFMessage, tempException); throw tempException; } } catch (RemoteException re) { // Not expected to get here since we are calling locally. tempAEFMessage.setMessage("There was a remote exception thrown in SAVoidTransactionActionImpl.performAction()."); log.error(tempAEFMessage, re); } if (log.isTraceEnabled()) { tempAEFMessage.setMessage("-Exit SAVoidTransactionActionImpl.performAction()."); log.trace(tempAEFMessage); } return null; } /** * Sends the key sequence required to start a transaction. * * @param wait True to wait for a state transition to state ITEMENTRY. * @result int Integer value representing the result of the key sequence. * @exception AEFException * AEFException error codes: * <br>AEFConst.CONFIG_ERROR, AEFConst.FACTORY_ERROR */ public int sendStartTransactionSequence(boolean wait) throws AEFException { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter SAVoidTransactionActionImpl.sendStartTransactionSequence()."); log.trace(tempAEFMessage); } int retVal = -1; AEFErrorHandler errorHandler = null; args.clear(); args.put("SEQUENCE_ID", "startTransaction"); keySequenceAction = (AEFAction)(actionFactory.makeAction(new ActionRequest("SimpleKeySequenceAction", args))); if (wait) { AbstractPropertyCondition[] conditions = { new PropertyEqualsCondition(POSDeviceProperties.CATEGORY, POSDeviceProperties.POS_STATE, mainState) }; lock = new ConditionLock(); if (perfTrace.isEnabled(AEFPerfTrace. COARSE)) { perfTrace.reportTimer(AEFPerfTrace. COARSE, sessionID, "voidTransaction", ">>>Sending start transaction key sequence to application."); } retVal = lock.performActionAndWait("send-start-transaction-sequence", keySequenceAction, conditions, BadConditionsImpl.getInstance().getBadConditions(), getTimeout()); if (retVal < 0) { errorHandler = new AEFErrorHandler("Send Start Transaction Sequence Error"); retVal = errorHandler.handleError(lock, keySequenceAction, conditions, BadConditionsImpl.getInstance().getBadConditions(), getTimeout(), retVal); if (retVal < 0) { tempAEFMessage.setMessage("Send Start Transaction Sequence Error"); log.error(tempAEFMessage, errorHandler.getAllExceptions()); throw errorHandler.getAllExceptions(); } } } else { if (perfTrace.isEnabled(AEFPerfTrace. COARSE)) { perfTrace.reportTimer(AEFPerfTrace. COARSE, sessionID, "voidTransaction", ">>>Sending start transaction key sequence to application."); } keySequenceAction.performAction(); } if (perfTrace.isEnabled(AEFPerfTrace. COARSE)) { perfTrace.reportTimer(AEFPerfTrace. COARSE, sessionID, "voidTransaction", "<<<Start transaction key sequence processed by application."); } if (log.isTraceEnabled()) { tempAEFMessage.setMessage("-Exit SAVoidTransactionActionImpl.sendStartTransactionSequence()."); log.trace(tempAEFMessage); } return retVal; } /** * Sends the Total key sequence. * * @param wait True to wait for a state transition to state ITEMENTRY. * @result int Integer value representing the result of the key sequence. * @exception AEFException * AEFException error codes: * <br>AEFConst.CONFIG_ERROR, AEFConst.FACTORY_ERROR */ public int sendTotalSequence(boolean wait) throws AEFException { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter SAVoidTransactionActionImpl.sendTotalSequence()."); log.trace(tempAEFMessage); } int retVal = -1; AEFErrorHandler errorHandler = null; args.clear(); args.put("SEQUENCE_ID", "total"); keySequenceAction = (AEFAction)(actionFactory.makeAction(new ActionRequest("SimpleKeySequenceAction", args))); if (wait) { AbstractPropertyCondition[] conditions = { new PropertyEqualsCondition(POSDeviceProperties.CATEGORY, POSDeviceProperties.POS_STATE, mainState), }; lock = new ConditionLock(); if (perfTrace.isEnabled(AEFPerfTrace. COARSE)) { perfTrace.reportTimer(AEFPerfTrace. COARSE, sessionID, "voidTransaction", ">>>Sending total key sequence to application."); } retVal = lock.performActionAndWait("send-total-sequence", keySequenceAction, conditions, BadConditionsImpl.getInstance().getBadConditions(), getTimeout()); if (retVal < 0) { errorHandler = new AEFErrorHandler("Send Total Sequence Error"); retVal = errorHandler.handleError(lock, keySequenceAction, conditions, BadConditionsImpl.getInstance().getBadConditions(), getTimeout(), retVal); if (retVal < 0) { tempAEFMessage.setMessage("Send Total Sequence Error"); log.error(tempAEFMessage, errorHandler.getAllExceptions()); throw errorHandler.getAllExceptions(); } } } else { if (perfTrace.isEnabled(AEFPerfTrace. COARSE)) { perfTrace.reportTimer(AEFPerfTrace. COARSE, sessionID, "voidTransaction", ">>>Sending total key sequence to application."); } keySequenceAction.performAction(); } if (perfTrace.isEnabled(AEFPerfTrace. COARSE)) { perfTrace.reportTimer(AEFPerfTrace. COARSE, sessionID, "voidTransaction", "<<<Total key sequence processed by application."); } if (log.isTraceEnabled()) { tempAEFMessage.setMessage("-Exit SAVoidTransactionActionImpl.sendTotalSequence()."); log.trace(tempAEFMessage); } return retVal; } /** * Sends the key sequence required to void a transaction when not in ITEMENTRY state. * * @param wait True to wait for a state transition to state ITEMENTRY. * @result int Integer value representing the result of the key sequence. * @exception AEFException * AEFException error codes: * <br>AEFConst.CONFIG_ERROR, AEFConst.FACTORY_ERROR */ public int sendVoidSequence(boolean wait) throws AEFException { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter SAVoidTransactionActionImpl.sendVoidSequence()."); log.trace(tempAEFMessage); } int retVal = -1; AEFErrorHandler errorHandler = null; args.clear(); args.put("SEQUENCE_ID", "voidTransaction"); keySequenceAction = (AEFAction)(actionFactory.makeAction(new ActionRequest("SimpleKeySequenceAction", args))); if (log.isDebugEnabled()) { tempAEFMessage.setMessage("SAVoidTransactionActionImp.sendVoidSequence: Return Value = " + retVal + " State = " + getCurrentState() + " Substate = " + getCurrentSubstate() + "."); log.debug(tempAEFMessage); } if (wait) { Condition clearConditions[] = { new PropertyEqualsCondition(POSDeviceProperties.CATEGORY, POSDeviceProperties.POS_STATE, mainState), new PropertyEqualsCondition(POSDeviceProperties.CATEGORY, POSDeviceProperties.POS_SUB_STATE, mainSubState) }; Condition conditions[] = { new AndCondition(clearConditions) }; lock = new ConditionLock(); if (perfTrace.isEnabled(AEFPerfTrace. COARSE)) { perfTrace.reportTimer(AEFPerfTrace. COARSE, sessionID, "voidTransaction", ">>>Sending void transaction key sequence to application."); } retVal = lock.performActionAndWait("wait-for-state-main", keySequenceAction, conditions, BadConditionsImpl.getInstance().getBadConditions(), getTimeout()); if (retVal < 0) { errorHandler = new AEFErrorHandler("Send Void Sequence Error"); retVal = errorHandler.handleError(lock, keySequenceAction, conditions, BadConditionsImpl.getInstance().getBadConditions(), getTimeout(), retVal); if (retVal < 0) { tempAEFMessage.setMessage("Send Void Sequence Error"); log.error(tempAEFMessage, errorHandler.getAllExceptions()); throw errorHandler.getAllExceptions(); } } } else { if (perfTrace.isEnabled(AEFPerfTrace. COARSE)) { perfTrace.reportTimer(AEFPerfTrace. COARSE, sessionID, "voidTransaction", ">>>Sending void transaction key sequence to application."); } keySequenceAction.performAction(); } if (perfTrace.isEnabled(AEFPerfTrace. COARSE)) { perfTrace.reportTimer(AEFPerfTrace. COARSE, sessionID, "voidTransaction", "<<<Void transaction key sequence processed by application."); } if (log.isTraceEnabled()) { tempAEFMessage.setMessage("-Exit SAVoidTransactionActionImpl.sendVoidSequence()."); log.trace(tempAEFMessage); } return retVal; } /** * Sends the key sequence required to void the transaction when in ITEMENTRY state. * * * @return int An integer index representing the result of the key sequence. * @exception AEFException * AEFException error codes are: * <br>AEFConst.CONFIG_ERROR, AEFConst.FACTORY_ERROR */ public int sendVoidSequence() throws AEFException { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter SAVoidTransactionActionImpl.sendVoidSequence()."); log.trace(tempAEFMessage); } int retVal = -1; AEFErrorHandler errorHandler = null; args.clear(); args.put("SEQUENCE_ID", "voidTransaction"); keySequenceAction = (AEFAction)(actionFactory.makeAction(new ActionRequest("SimpleKeySequenceAction", args))); AbstractPropertyCondition[] conditions = { new PropertyEqualsCondition(POSDeviceProperties.CATEGORY, POSDeviceProperties.POS_SUB_STATE, mainSubState) }; lock = new ConditionLock(); if (perfTrace.isEnabled(AEFPerfTrace. COARSE)) { perfTrace.reportTimer(AEFPerfTrace. COARSE, sessionID, "voidTransaction", ">>>Sending void transaction key sequence to application."); } retVal = lock.performActionAndWait("wait-for-void-transaction", keySequenceAction, conditions, BadConditionsImpl.getInstance().getExtendedBadConditions(), getTimeout()); if (log.isDebugEnabled()) { tempAEFMessage.setMessage("SAVoidTransactionActionImp.sendVoidSequence: Return Value = " + retVal + " State = " + getCurrentState() + " Substate = " + getCurrentSubstate() + "."); log.debug(tempAEFMessage); } if (retVal < 0) { errorHandler = new AEFErrorHandler("Send Void Sequence Error"); retVal = errorHandler.handleError(lock, keySequenceAction, conditions, BadConditionsImpl.getInstance().getExtendedBadConditions(), getTimeout(), retVal); if (retVal < 0) { tempAEFMessage.setMessage("Send Void Sequence Error"); log.error(tempAEFMessage, errorHandler.getAllExceptions()); throw errorHandler.getAllExceptions(); } } if (perfTrace.isEnabled(AEFPerfTrace. COARSE)) { perfTrace.reportTimer(AEFPerfTrace. COARSE, sessionID, "voidTransaction", "<<<Void transaction key sequence processed by application."); } if (log.isTraceEnabled()) { tempAEFMessage.setMessage("-Exit SAVoidTransactionActionImpl.sendVoidSequence()."); log.trace(tempAEFMessage); } return retVal; } /** * Sends the key sequence required to clear an error. * * @param wait True to wait for a state transition to state ITEMENTRY. * @result int Integer value representing the result of the key sequence. * @exception AEFException * AEFException error codes: * <br>AEFConst.CONFIG_ERROR, AEFConst.FACTORY_ERROR */ public int sendClearSequence(boolean wait) throws AEFException { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter SAVoidTransactionActionImpl.sendClearSequence()."); log.trace(tempAEFMessage); } int retVal = -1; AEFErrorHandler errorHandler = null; args.clear(); args.put("SEQUENCE_ID", "clear-error"); keySequenceAction = (AEFAction)(actionFactory.makeAction(new ActionRequest("SimpleKeySequenceAction", args))); if (wait) { AbstractPropertyCondition[] conditions = { new PropertyNotEqualsCondition(POSDeviceProperties.CATEGORY, POSDeviceProperties.POS_STATE, clearState) }; lock = new ConditionLock(); if (perfTrace.isEnabled(AEFPerfTrace. COARSE)) { perfTrace.reportTimer(AEFPerfTrace. COARSE, sessionID, "voidTransaction", ">>>Sending clear key sequence to application."); } retVal = lock.performActionAndWait("wait-for-state-main", keySequenceAction, conditions, BadConditionsImpl.getInstance().getBadConditions(), getTimeout()); if (retVal < 0) { errorHandler = new AEFErrorHandler("Send Clear Sequence Error"); retVal = errorHandler.handleError(lock, keySequenceAction, conditions, BadConditionsImpl.getInstance().getBadConditions(), getTimeout(), retVal); if (retVal < 0) { tempAEFMessage.setMessage("Send Void Sequence Error"); log.error(tempAEFMessage, errorHandler.getAllExceptions()); throw errorHandler.getAllExceptions(); } } } else { if (perfTrace.isEnabled(AEFPerfTrace. COARSE)) { perfTrace.reportTimer(AEFPerfTrace. COARSE, sessionID, "voidTransaction", ">>>Sending clear key sequence to application."); } keySequenceAction.performAction(); } if (perfTrace.isEnabled(AEFPerfTrace. COARSE)) { perfTrace.reportTimer(AEFPerfTrace. COARSE, sessionID, "voidTransaction", "<<<Clear key sequence processed by application."); } if (log.isTraceEnabled()) { tempAEFMessage.setMessage("-Exit SAVoidTransactionActionImpl.sendClearSequence()."); log.trace(tempAEFMessage); } return retVal; } /** * Sends the key sequence required to move us from SPEC-SO to OVERRIDE state. * * @param wait True to wait for a state transition to state OVERRIDE. * @result int Integer value representing the result of the key sequence. * @exception AEFException * AEFException error codes: * <br>AEFConst.CONFIG_ERROR, AEFConst.FACTORY_ERROR */ public int sendSpecsoToOverrideSequence(boolean wait) throws AEFException { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter SAVoidTransactionActionImpl.sendSpecsoToOverrideSequence()."); log.trace(tempAEFMessage); } int retVal = -1; AEFErrorHandler errorHandler = null; args.clear(); args.put("SEQUENCE_ID", "specialSignonToOverride"); keySequenceAction = (AEFAction)(actionFactory.makeAction(new ActionRequest("SimpleKeySequenceAction", args))); if (wait) { AbstractPropertyCondition[] conditions = { new PropertyEqualsCondition(POSDeviceProperties.CATEGORY, POSDeviceProperties.POS_STATE, clearState) }; lock = new ConditionLock(); if (perfTrace.isEnabled(AEFPerfTrace. COARSE)) { perfTrace.reportTimer(AEFPerfTrace. COARSE, sessionID, "voidTransaction", ">>>Sending signon key sequence to application."); } retVal = lock.performActionAndWait("wait-for-state-OVERRIDE", keySequenceAction, conditions, BadConditionsImpl.getInstance().getBadConditions(), getTimeout()); if (retVal < 0) { errorHandler = new AEFErrorHandler("Send Special to Override Sequence Error"); retVal = errorHandler.handleError(lock, keySequenceAction, conditions, BadConditionsImpl.getInstance().getBadConditions(), getTimeout(), retVal); if (retVal < 0) { tempAEFMessage.setMessage("Send Special to Override Sequence Error"); log.error(tempAEFMessage, errorHandler.getAllExceptions()); throw errorHandler.getAllExceptions(); } } } else { if (perfTrace.isEnabled(AEFPerfTrace. COARSE)) { perfTrace.reportTimer(AEFPerfTrace. COARSE, sessionID, "voidTransaction", ">>>Sending signon key sequence to application."); } keySequenceAction.performAction(); } if (perfTrace.isEnabled(AEFPerfTrace. COARSE)) { perfTrace.reportTimer(AEFPerfTrace. COARSE, sessionID, "voidTransaction", ">>>Signon key sequence processed by application."); } if (log.isTraceEnabled()) { tempAEFMessage.setMessage("-Exit SAVoidTransactionActionImpl.sendSpecsoToOverrideSequence()."); log.trace(tempAEFMessage); } return retVal; } /** * Initialize the sub-state variables for SA. * * @result void */ private void initializeSubStates() { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter SAVoidTransactionActionImpl.initializeSubStates()."); log.trace(tempAEFMessage); } mainSubState = Substate.getSubstate("SELECT_PROCEDURE"); if (log.isTraceEnabled()) { tempAEFMessage.setMessage("-Exit SAVoidTransactionActionImpl.initializeSubStates()."); log.trace(tempAEFMessage); } } /** * Initialize the state variables for SA. * * @result void */ private void initializeStates() { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter SAVoidTransactionActionImpl.initializeStates()."); log.trace(tempAEFMessage); } // Get the values for all the SA application states. clearState = State.getState("CLEAR"); idState = State.getState("ID"); passwordState = State.getState("PASSWORD"); soPasswordState = State.getState("SO_PASSWORD"); securedState = State.getState("SECURED"); overrideState = State.getState("OVERRIDE"); acctNoState = State.getState("ACCT_NUMBER"); acctOvrState = State.getState("ACCT_OVERRIDE"); enterClearState = State.getState("ENTER_CLEAR"); mainState = State.getState("ITEMENTRY"); enterDataState = State.getState("ENTER_DATA"); standaloneState = State.getState("STANDALONE"); enterState = State.getState("ENTER"); eftAccountState = State.getState("EFT_ACCOUNT"); eftBlinqState = State.getState("EFT_BLINQ"); tenderCashingExchangeState = State.getState("TENDER_CASHING_EXCHANGE"); cashierLoanPickupTenderCountState = State.getState("CASHIER_LOAN_PICKUP_TENDER_COUNT"); tenderListState = State.getState("TENDER_LIST"); terminalTransferMonitorState = State.getState("TERMINAL_TRANSFER_MONITOR"); priceVerifyState = State.getState("PRICE_VERIFY_CHANGE"); eftVoid1State = State.getState("EFTVOID1"); eftVoid2State = State.getState("EFTVOID2"); micrTransactionState = State.getState("MICRTRAN"); micrAccountState = State.getState("MICRACCT"); micrSequenceState = State.getState("MICRSEQN"); autoSignState = State.getState("AUTOSIGN"); if (log.isTraceEnabled()) { tempAEFMessage.setMessage("-Exit SAVoidTransactionActionImpl.initializeStates()."); log.trace(tempAEFMessage); } } /** * Calls the Error Handler to try to clear an error. * * @result int Integer value representing the result of the key sequence. * @exception AEFException */ public int handleError() throws AEFException { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter SAVoidTransactionActionImpl.handleError()."); log.trace(tempAEFMessage); } int retVal = -1; AEFErrorHandler errorHandler = null; args.clear(); args.put("SEQUENCE_ID", "clear-error"); keySequenceAction = (AEFAction)(actionFactory.makeAction(new ActionRequest("SimpleKeySequenceAction", args))); AbstractPropertyCondition[] conditions = { new PropertyEqualsCondition(POSDeviceProperties.CATEGORY, POSDeviceProperties.POS_STATE, mainState), new PropertyEqualsCondition(POSDeviceProperties.CATEGORY, POSDeviceProperties.POS_STATE, idState), new PropertyEqualsCondition(POSDeviceProperties.CATEGORY, POSDeviceProperties.POS_STATE, overrideState) }; lock = new ConditionLock(); errorHandler = new AEFErrorHandler("There was an error in SAForcedLogoffActionImpl.sendClearSequence()"); retVal = errorHandler.handleError(lock, keySequenceAction, conditions, BadConditionsImpl.getInstance().getBadConditions(), getTimeout(), retVal); if (retVal < 0) { tempAEFMessage.setMessage("There was an error in SAForcedLogoffActionImpl.sendClearSequence()"); log.error(tempAEFMessage, errorHandler.getAllExceptions()); throw errorHandler.getAllExceptions(); } if (log.isTraceEnabled()) { tempAEFMessage.setMessage("-Exit SAVoidTransactionActionImpl.handleError()."); log.trace(tempAEFMessage); } return retVal; } // Instance Variables protected AEFAction keySequenceAction = null; protected ConditionLock lock = null; protected String idState = null; protected String clearState = null; protected String passwordState = null; protected String soPasswordState = null; protected String securedState = null; protected String overrideState = null; protected String acctNoState = null; protected String acctOvrState = null; protected String enterClearState = null; protected String mainState = null; protected String enterDataState = null; protected String standaloneState = null; protected String enterState = null; protected String eftAccountState = null; protected String eftBlinqState = null; protected String tenderCashingExchangeState = null; protected String cashierLoanPickupTenderCountState = null; protected String tenderListState = null; protected String terminalTransferMonitorState = null; protected String priceVerifyState = null; protected String eftVoid1State = null; protected String eftVoid2State = null; protected String micrTransactionState = null; protected String micrAccountState = null; protected String micrSequenceState = null; protected String autoSignState = null; protected String mainSubState = null; private static Log log = LogFactory.getLog(SAVoidTransactionActionImpl.class); }