/*
* ACEEPSCreditTenderActionImpl
*
* 9/3/2003
*
* 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 java.rmi.RemoteException;
import java.util.Vector;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.ibm.retail.AEF.automation.ActionRequest;
import com.ibm.retail.AEF.automation.AndCondition;
import com.ibm.retail.AEF.automation.Condition;
import com.ibm.retail.AEF.automation.CreditIdentifier;
import com.ibm.retail.AEF.automation.DetectorAccess;
import com.ibm.retail.AEF.automation.ItemIdentifier;
import com.ibm.retail.AEF.automation.MSRCreditIdentifier;
import com.ibm.retail.AEF.automation.ObjectDetector;
import com.ibm.retail.AEF.automation.OrCondition;
import com.ibm.retail.AEF.automation.PropertyEqualsCondition;
import com.ibm.retail.AEF.automation.State;
import com.ibm.retail.AEF.automation.Substate;
import com.ibm.retail.AEF.automation.TenderIdentifier;
import com.ibm.retail.AEF.automation.TenderMapperImpl;
import com.ibm.retail.AEF.data.POSDeviceProperties;
import com.ibm.retail.AEF.data.TransactionStatusProperties;
import com.ibm.retail.AEF.data.WorkstationStatusProperties;
import com.ibm.retail.AEF.event.AEFPropertyChangeEvent;
import com.ibm.retail.AEF.event.AEFPropertyChangeListener;
import com.ibm.retail.AEF.session.SessionContext;
import com.ibm.retail.AEF.thread.ConditionLock;
import com.ibm.retail.AEF.thread.ObjectDetectorLock;
import com.ibm.retail.AEF.util.AEFErrorHandler;
import com.ibm.retail.AEF.util.AEFUtilities;
import com.ibm.retail.AEF.util.BadConditionsImpl;
import com.ibm.retail.si.util.AEFConst;
import com.ibm.retail.si.util.AEFException;
/**
* ACEEPSCreditTenderActionImpl is a class which the POSAutomationProvider uses to accomplish
* adding an EFT credit tender into a transaction on the POS application.
*
*/
public class ACEEPSCreditTenderActionImpl extends ACEActionImpl
implements AEFPropertyChangeListener
{
static String copyright()
{ return com.ibm.retail.si.Copyright.IBM_COPYRIGHT_SHORT; }
private static Log log = LogFactory.getLog(ACEEPSCreditTenderActionImpl.class);
/**
* Constructor
*
* We assume that a non-null amount is provided and that the format of the
* amount has been validated (i.e., numeric, with or without currency symbols).
*
* @param request The ActionRequest which contains a HashMap of arguments.
* @exception com.ibm.retail.AEF.util.AEFException
* AEFException return codes are:
*
AEFConst.INVALID_ARGUMENT, AEFConst.INVALID_TENDER_TYPE
*
*/
public ACEEPSCreditTenderActionImpl(ActionRequest request) throws AEFException
{
super(request);
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("+Enter constructor of ACEEPSCreditTenderActionImpl.");
log.trace(tempAEFMessage);
}
useTrackData = false;
// validSubstates contains a list of all the substates for which
// an item may be entered. This is a class static, so it is only
// initialized once.
// these are the only valid substates for credit tenders. Note that there
// is an additional substate - EXPECTING_FOODSTAMP_TENDER - that will need
// to be checked for foodstamp tenders
if (validSubstates == null)
{
validSubstates = new Vector();
validSubstates.addElement(Substate.getSubstate("EXPECTING_ITEM"));
validSubstates.addElement(Substate.getSubstate("EXPECTING_TENDER"));
}
tenderID = (TenderIdentifier)(request.getArguments());
amount = tenderID.getAmount();
// amount has already been validated
// Strip out any non-numeric portion of the amount (currency symbol & decimal separator)
amount = AEFUtilities.formatNumericOnly(amount);
String cardType = null;
if (tenderID instanceof CreditIdentifier)
{
creditID = (CreditIdentifier) (tenderID);
accountNumber = creditID.getAccountNumber();
expDate = creditID.getExpirationDate();
cardType = creditID.getCardType();
}
else if (tenderID instanceof MSRCreditIdentifier)
{
MSRCreditIdentifier msrCreditID = (MSRCreditIdentifier) (tenderID);
track1Data = msrCreditID.getTrack1Data();
track2Data = msrCreditID.getTrack2Data();
track3Data = msrCreditID.getTrack3Data();
cardType = msrCreditID.getCardType();
useTrackData = true;
}
// Try to determine the tender variety if a card type was given.
if (cardType != null && !cardType.equals(CreditIdentifier.UNKNOWN) && cardType != "")
{
// A card type was specified. Use the tender mapper to try to find out the
// tender variety.
String tenderKey = TenderMapperImpl.getInstance().getKey(cardType);
if (tenderKey == null)
{
String tempString = "ACEEPSCreditTenderActionImpl(" + tenderID + "): Credit card type \"" + cardType + "\" doesn't match any tender description in tendermap.properties.";
AEFException tempException = new AEFException(AEFConst.INVALID_ARGUMENT,
AEFConst.INVALID_TENDER_TYPE,
tempString);
tempAEFMessage.setMessage(tempString);
log.error(tempAEFMessage, tempException);
throw tempException;
}
else
{
tenderVariety = TenderMapperImpl.getInstance().getVariety(tenderKey);
}
}
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("-Exit constructor of ACEEPSCreditTenderActionImpl.");
log.trace(tempAEFMessage);
}
}
/**
* Perform the action represented by the ActionRequest and return an ActionResult.
*
*
* @param request The ActionRequest which contains the classname and arguments.
* @return Object The Tender instance.
* @exception com.ibm.retail.AEF.util.AEFException
* Among the possible AEFException error codes are:
*
AEFConst.INVALID_ARGUMENT, AEFConst.INVALID_TENDER_TYPE
*
AEFConst.APPLICATION_LIMIT_EXCEEDED, AEFConst.ACCOUNT_TENDER_LIMIT
*
AEFConst.APPLICATION_LIMIT_EXCEEDED, AEFConst.CHANGE_AMOUNT_LIMIT
*
AEFConst.APPLICATION_LIMIT_EXCEEDED, AEFConst.NUMBER_OF_TENDERS_LIMIT
*
AEFConst.APPLICATION_LIMIT_EXCEEDED, AEFConst.STAND_IN_COUNT_LIMIT
*
AEFConst.APPLICATION_LIMIT_EXCEEDED, AEFConst.STAND_IN_AMOUNT_LIMIT
*
AEFConst.APPLICATION_LIMIT_EXCEEDED, AEFConst.CARD_EXPIRED
*
AEFConst.APPLICATION_LIMIT_EXCEEDED, AEFConst.TENDER_FLOOR_LIMIT
*
AEFConst.PROCEDURE_NOT_ALLOWED, AEFConst.EXTERNAL_TENDER_AUTHORIZATION_SUSPENDED
*
AEFConst.TENDER_NOT_ACCEPTED, AEFConst.TENDER_NOT_AUTHORIZED
*
AEFConst.TENDER_NOT_ACCEPTED, AEFConst.RISK_1
*
AEFConst.TENDER_NOT_ACCEPTED, AEFConst.RISK_2
*
AEFConst.TENDER_NOT_ACCEPTED, AEFConst.RISK_3
*
AEFConst.TENDER_NOT_ACCEPTED, AEFConst.RISK_4
*
AEFConst.TENDER_NOT_ACCEPTED, AEFConst.VERIFICATION_TIMEOUT
*
AEFConst.TENDER_NOT_ACCEPTED, AEFConst.CREDIT_NOT_AVAILABLE
*
AEFConst.TENDER_NOT_ACCEPTED, AEFConst.TOO_LONG_IN_STANDIN
*
AEFConst.TENDER_NOT_ACCEPTED, AEFConst.UNKNOWN_SERVICER
*
AEFConst.TENDER_NOT_ACCEPTED, AEFConst.SERVICER_CLOSED
*
AEFConst.TENDER_NOT_ACCEPTED, AEFConst.CARD_TYPE_UNKNOWN
*
AEFConst.TENDER_NOT_ACCEPTED, AEFConst.TENDER_NOT_AUTHORIZED
*
AEFConst.TENDER_NOT_ACCEPTED, AEFConst.PAYMENT_SYSTEM_OFFLINE
*
AEFConst.TENDER_NOT_ACCEPTED, AEFConst.UNKNOWN_SERVICER
*
AEFConst.INVALID_MANAGER_OVERRIDE_NUMBER
*
AEFConst.KEYLOCK_ERROR, AEFConst.MANAGER_KEY_REQUIRED
*
AEFConst.MSR_HOOK_SWIPE_ERROR, AEFConst.MSR_SET_TO_DECODE
*
AEFConst.MSR_HOOK_SWIPE_ERROR, AEFConst.MSR_NOT_ENABLED
*
AEFConst.JAVA_POS_EXCEPTION, see exception cause () for actual javaPos exception
*
AEFConst.INVALID_ARGUMENT
*
Common Errors
*/
public Object performAction() throws AEFException
{
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("+Enter ACEEPSCreditTenderActionImpl.performAction()");
log.trace(tempAEFMessage);
}
super.performAction(); // Call super to perform any common processing and clear any errors before we start.
Object retVal = null;
// If app is in secured state, and options are set to automatically do a special
// signon, then create the logon action to do the special signon first.
checkForSpecialSignon();
int seqResult = -1;
//Check precondition that app is in one of the substates which is valid for item entry.
//If not, throw exception.
String currentSubstate = getCurrentSubstate();
if (validSubstates.contains(currentSubstate))
{
// Application is in correct substate for tendering.
// Check if we need to send the total first.
if (currentSubstate.equals(Substate.getSubstate("EXPECTING_ITEM")))
{
seqResult = sendTotalSequence();
}
seqResult = sendTenderSequence();
if (seqResult==0)
{
// ENTER ACCOUNT NUMBER OVERRIDE OR CLEAR
if (useTrackData)
{
seqResult = swipeMSR(track1Data, track2Data, track3Data);
}
else
{
seqResult = sendAccountNumberSequence();
}
if (seqResult == 0)
{
// B309 APPROVED.
// Success, wait for Tender
// If we tendered out the transaction, we may get a
// REMOVE RECEIPT FOR CUSTOMER message we have to handle.
seqResult = waitForNextStateAfterTender();
retVal = waitForTender();
}
// -999 is a special case for b048 throw exception
if (seqResult == -999)
{
String tempString = "ACEEPSCreditTenderActionImpl.performAction(): Invalid account number. Account Number"
+ accountNumber + "Track 2 Data" + track2Data;
AEFException tempException = new AEFException(AEFConst.INVALID_ARGUMENT,
AEFConst.INVALID_ACCOUNT_NUMBER,
tempString);
tempAEFMessage.setMessage(tempString);
log.error(tempAEFMessage, tempException);
throw tempException;
}
}
}
else
{
// Not in valid state for item entry.
String tempString = "ACEEPSCreditTenderActionImpl.performAction(): POS application not in proper substate to tender credit.\n Application substate is " + currentSubstate + ".";
AEFException tempException = new AEFException(AEFConst.APPLICATION_NOT_IN_PROPER_STATE,
0,
tempString);
tempAEFMessage.setMessage(tempString);
log.error(tempAEFMessage, tempException);
throw tempException;
}
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("-Exit ACEEPSCreditTenderActionImpl.performAction()");
log.trace(tempAEFMessage);
}
return retVal;
}
/**
* Sends the "total" key sequence.
*
*
* @return int An integer value representing the result of the key sequence.
* @exception AEFException
*/
protected int sendTotalSequence() throws AEFException
{
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("+Enter ACEEPSCreditTenderActionImpl.sendTotalSequence()");
log.trace(tempAEFMessage);
}
int retVal = -1;
args.clear();
args.put("SEQUENCE_ID", "total");
keySequenceAction = (AEFAction)
(actionFactory.makeAction(new ActionRequest("SimpleKeySequenceAction", args)));
Condition goodConditions[] =
{
new PropertyEqualsCondition(POSDeviceProperties.CATEGORY,
POSDeviceProperties.POS_SUB_STATE,
Substate.getSubstate("EXPECTING_TENDER")),
};
lock = new ConditionLock();
retVal = lock.performActionAndWait("wait-for-expecting-tender-substate",
keySequenceAction,
goodConditions,
BadConditionsImpl.getInstance().getBadConditions(),
getTimeout());
if (retVal < 0)
{
AEFErrorHandler errorHandler = new AEFErrorHandler("Send Total Sequence Error");
retVal = errorHandler.handleError(lock,
keySequenceAction,
goodConditions,
BadConditionsImpl.getInstance().getBadConditions(),
getTimeout(),
retVal);
}
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("-Exit ACEEPSCreditTenderActionImpl.sendTotalSequence()");
log.trace(tempAEFMessage);
}
return retVal;
}
/**
* Sends the key sequence for the credit tender amount.
*
*
* @return int An integer value representing the result of the key sequence.
* @exception com.ibm.retail.AEF.util.AEFException
*/
protected int sendTenderSequence() throws AEFException
{
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("+Enter ACEEPSCreditTenderActionImpl.sendTenderSequence()");
log.trace(tempAEFMessage);
}
int retVal = -1;
args.clear();
StringBuffer sequenceIdBuf = new StringBuffer();
if (tenderVariety != null)
{
sequenceIdBuf.append("tenderVariety+");
args.put("%tenderVariety.0", tenderVariety);
}
sequenceIdBuf.append("creditAmount");
args.put("%creditAmount.0", amount);
args.put("SEQUENCE_ID", new String(sequenceIdBuf));
keySequenceAction = (AEFAction)
(actionFactory.makeAction(new ActionRequest("SimpleKeySequenceAction", args)));
Condition goodConditions[] =
{
new PropertyEqualsCondition(POSDeviceProperties.CATEGORY,
POSDeviceProperties.POS_STATE,
State.getState("ACCT_NUMBER")),
};
lock = new ConditionLock();
detector = ((DetectorAccess)(SessionContext.getSession())).getTenderDetector();
// Save any current tender instance number so we are sure to only get a tender
// created after this key sequence is sent.
instanceNumber = detector.getInstanceNumber();
retVal = lock.performActionAndWait("wait-for-account-number-guidance-prompt",
keySequenceAction,
goodConditions,
BadConditionsImpl.getInstance().getBadConditions(),
getTimeout());
if (retVal < 0)
{
AEFErrorHandler errorHandler = new AEFErrorHandler("Wait for account number state Error");
retVal = errorHandler.handleError(lock,
keySequenceAction,
goodConditions,
BadConditionsImpl.getInstance().getBadConditions(),
getTimeout(),
retVal);
}
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("-Exit ACEEPSCreditTenderActionImpl.sendTenderSequence()");
log.trace(tempAEFMessage);
}
return retVal;
}
/**
* Sends the account number for the credit tender.
*
*
* @return int An integer value representing the result of the key sequence.
* @exception AEFException
*/
protected int sendAccountNumberSequence() throws AEFException
{
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("+Enter ACEEPSCreditTenderActionImpl.sendAccountNumberSequence()");
log.trace(tempAEFMessage);
}
int retVal = -1;
args.clear();
args.put("%0", accountNumber);
args.put("SEQUENCE_ID", "accountNumber");
keySequenceAction = (AEFAction)
(actionFactory.makeAction(new ActionRequest("SimpleKeySequenceAction", args)));
try
{
dataProvider.setPropertyValue(TransactionStatusProperties.CATEGORY,
TransactionStatusProperties.LAST_CREDIT_APPROVED,
"false");
dataProvider.addAEFPropertyChangeListener(this,
POSDeviceProperties.CATEGORY,
POSDeviceProperties.POS_SUB_STATE);
}
catch (RemoteException re) { /* Can't get here. */ }
Condition goodConditions[] =
{
new PropertyEqualsCondition(TransactionStatusProperties.CATEGORY,
TransactionStatusProperties.LAST_CREDIT_APPROVED,
"true"),
new PropertyEqualsCondition(POSDeviceProperties.CATEGORY,
POSDeviceProperties.POS_SUB_STATE,
Substate.getSubstate("ACCOUNT_NUMBER_NEEDED")),
};
Condition badConditions[] = BadConditionsImpl.getInstance().getExtendedBadConditions();
lock = new ConditionLock();
try {
retVal = lock.performActionAndWait("wait-for-LAST-CREDIT-APPROVED",
keySequenceAction,
goodConditions,
badConditions,
getPaymentHostTimeout());
String currentSubstate = getCurrentSubstate();
boolean acctNumNeeded = false;
acctNumNeeded = currentSubstate.equals(Substate.getSubstate("ACCOUNT_NUMBER_NEEDED"));
if (acctNumNeeded)
{
sendClearSequence(true);
retVal = -999;
}
else if (retVal < 0)
{
AEFErrorHandler errorHandler = new AEFErrorHandler("Send Account Number Sequence Error", creditID);
retVal = errorHandler.handleError(lock,
keySequenceAction,
goodConditions,
badConditions,
getTimeout(), retVal);
}
} catch (AEFException e) {
tempAEFMessage.setMessage("There was an AEF exception thrown in sendAccountNumberSequence of ACEEPSCreditTenderActionImpl.");
log.error(tempAEFMessage, e);
throw e;
} finally {
try
{
dataProvider.removeAEFPropertyChangeListener(this,
POSDeviceProperties.CATEGORY,
POSDeviceProperties.POS_SUB_STATE);
}
catch (RemoteException re) { /* Can't get here. */ }
}
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("-Exit ACEEPSCreditTenderActionImpl.sendAccountNumberSequence()");
log.trace(tempAEFMessage);
}
return retVal;
}
/**
* Sends credit data as if MSR swiped.
*
*
* @return int An integer value representing the result of the key sequence.
* @exception AEFException
*/
protected int swipeMSR(byte[] track1Data, byte[] track2Data, byte[] track3Data) throws AEFException
{
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("+Enter ACEEPSCreditTenderActionImpl.swipeMSR()");
log.trace(tempAEFMessage);
}
int retVal = -1;
args.clear();
args.put("TRACK1DATA", track1Data);
args.put("TRACK2DATA", track2Data);
args.put("TRACK3DATA", track3Data);
keySequenceAction = (AEFAction)
(actionFactory.makeAction(new ActionRequest("SwipeMSRAction", args)));
try
{
dataProvider.setPropertyValue(TransactionStatusProperties.CATEGORY,
TransactionStatusProperties.LAST_CREDIT_APPROVED,
"false");
dataProvider.addAEFPropertyChangeListener(this,
POSDeviceProperties.CATEGORY,
POSDeviceProperties.POS_SUB_STATE);
}
catch (RemoteException re) { /* Can't get here. */ }
Condition goodConditions[] =
{
new PropertyEqualsCondition(TransactionStatusProperties.CATEGORY,
TransactionStatusProperties.LAST_CREDIT_APPROVED,
"true"),
new PropertyEqualsCondition(POSDeviceProperties.CATEGORY,
POSDeviceProperties.POS_SUB_STATE,
Substate.getSubstate("ACCOUNT_NUMBER_NEEDED")),
};
Condition badConditions[] = BadConditionsImpl.getInstance().getExtendedBadConditions();
lock = new ConditionLock();
try {
retVal = lock.performActionAndWait("wait-for-LAST-CREDIT-APPROVED",
keySequenceAction,
goodConditions,
badConditions,
getPaymentHostTimeout());
String currentSubstate = getCurrentSubstate();
boolean acctNumNeeded = false;
acctNumNeeded = currentSubstate.equals(Substate.getSubstate("ACCOUNT_NUMBER_NEEDED"));
if (acctNumNeeded)
{
sendClearSequence(true);
retVal = -999;
}
else if (retVal < 0)
{
AEFErrorHandler errorHandler = new AEFErrorHandler("Swipe MSR Error", tenderID);
retVal = errorHandler.handleError(lock,
keySequenceAction,
goodConditions,
badConditions,
getTimeout(), retVal);
}
} catch (AEFException e) {
tempAEFMessage.setMessage("There was an AEF exception thrown in swipeMSR() of ACEEPSCreditTenderActionImpl.");
log.error(tempAEFMessage, e);
throw e;
} finally {
try {
dataProvider.removeAEFPropertyChangeListener(this,
POSDeviceProperties.CATEGORY,
POSDeviceProperties.POS_SUB_STATE);
} catch (RemoteException re) { /* Can't get here. */ }
}
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("-Exit ACEEPSCreditTenderActionImpl.swipeMSR()");
log.trace(tempAEFMessage);
}
return retVal;
}
/**
* Waits for the next states after the tender was successful. This is necessary
* because the transaction may have been tendered out, in which case we will
* get a "REMOVE RECEIPT FOR CUSTOMER" prompt which must be cleared.
*
*
* @return int An integer value representing the result of the key sequence.
* @exception AEFException
*/
protected int waitForNextStateAfterTender() throws AEFException
{
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("+Enter ACEEPSCreditTenderActionImpl.waitForNextStateAfterTender()");
log.trace(tempAEFMessage);
}
int retVal = -1;
Condition[] goodSubstates =
{
new PropertyEqualsCondition(POSDeviceProperties.CATEGORY,
POSDeviceProperties.POS_SUB_STATE,
Substate.getSubstate("SELECT_PROCEDURE")),
new PropertyEqualsCondition(POSDeviceProperties.CATEGORY,
POSDeviceProperties.POS_SUB_STATE,
Substate.getSubstate("EXPECTING_PROCEDURE")),
};
Condition[] txnOverConditions =
{
new OrCondition(goodSubstates),
new PropertyEqualsCondition(POSDeviceProperties.CATEGORY,
POSDeviceProperties.POS_STATE,
State.getState("MAIN")),
new PropertyEqualsCondition(WorkstationStatusProperties.CATEGORY,
WorkstationStatusProperties.SALES_TRANSACTION_IN_PROGRESS,
"false"),
};
Condition[] goodConditions =
{
new PropertyEqualsCondition(POSDeviceProperties.CATEGORY,
POSDeviceProperties.POS_SUB_STATE,
Substate.getSubstate("EXPECTING_TENDER")),
new AndCondition(txnOverConditions),
};
Condition[] removeReceiptCondition =
{
new PropertyEqualsCondition(POSDeviceProperties.CATEGORY,
POSDeviceProperties.POS_SUB_STATE,
Substate.getSubstate("REMOVE_CUSTOMER_RECEIPT")),
};
Condition[] badConditions = BadConditionsImpl.getInstance().getBadConditions(removeReceiptCondition);
lock = new ConditionLock();
retVal = lock.wait("wait-for-next-state-after-tender-accepted",
goodConditions,
badConditions,
getTimeout(),
true);
if (retVal < 0)
{
AEFErrorHandler errorHandler = new AEFErrorHandler("After Tender Sequence Error");
retVal = errorHandler.handleError(lock,
keySequenceAction,
goodConditions,
badConditions,
getTimeout(),
retVal);
}
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("-Exit ACEEPSCreditTenderActionImpl.waitForNextStateAfterTender()");
log.trace(tempAEFMessage);
}
return retVal;
}
/**
* Waits for a new tender line item to be detected.
*
*
* @return Object The newly detected tender. (Note in this case, it's an ArrayList that
* contains the tender object).
* @exception AEFException
*/
protected Object waitForTender() throws AEFException
{
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("+Enter ACEEPSCreditTenderActionImpl.waitForTender()");
log.trace(tempAEFMessage);
}
Object retVal = null;
ObjectDetectorLock objLock = new ObjectDetectorLock();
retVal = objLock.waitForNewObject("wait-for-tender", detector, instanceNumber, getTimeout());
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("-Exit ACEEPSCreditTenderActionImpl.waitForTender()");
log.trace(tempAEFMessage);
}
return retVal;
}
/**
* A AEF POSDataProvider property was updated.
* We will be looking for a substate change to "APPROVED"
*
* @param evt contains details of the event
*
*/
public void propertyChanged(AEFPropertyChangeEvent evt)
{
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("+Enter ACEEPSCreditTenderActionImpl.propertyChanged()");
log.trace(tempAEFMessage);
}
// Because we only registered for substate events, this event must contain a substate value.
String substate = (String)(evt.getNewValue());
if (substate.equals(Substate.getSubstate("TENDER_APPROVED")))
{
// Credit was approved, set the POSDataProvider property.
try
{
dataProvider.setPropertyValue(TransactionStatusProperties.CATEGORY,
TransactionStatusProperties.LAST_CREDIT_APPROVED,
"true");
}
catch (RemoteException re) { /* Can't get here. */ }
}
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("-Exit ACEEPSCreditTenderActionImpl.propertyChanged()");
log.trace(tempAEFMessage);
}
}
/* Instance Variables */
protected CreditIdentifier creditID;
protected TenderIdentifier tenderID;
protected AEFAction keySequenceAction;
protected ItemIdentifier itemID;
protected ConditionLock lock;
protected ObjectDetector detector;
protected int instanceNumber;
protected static Vector validSubstates;
protected String amount;
protected String accountNumber;
protected String expDate;
protected String tenderVariety;
protected byte[] track1Data;
protected byte[] track2Data;
protected byte[] track3Data;
protected boolean useTrackData;
}