package com.gpc.client.pointofsale.invoice; import java.awt.Component; import java.awt.Container; import java.awt.Frame; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.FocusEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.math.BigDecimal; import java.rmi.RemoteException; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Vector; import javax.comm.NoSuchPortException; import javax.comm.PortInUseException; import javax.comm.UnsupportedCommOperationException; import javax.swing.DefaultComboBoxModel; import javax.swing.FocusManager; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JRadioButton; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.WindowConstants; import javax.swing.border.Border; import javax.swing.border.TitledBorder; import org.apache.log4j.Logger; import com.gpc.tams.comm.io.PhoneRoomTaapRouter; import com.gpc.tams.comm.io.TaapRouter; import com.gpc.businessservice.factory.loyalty.LoyaltyProgramServiceFactory; import com.gpc.businessservice.factory.paymentcard.PaymentCardServiceFactory; import com.gpc.businessservice.factory.rads.RadsServiceFactory; import com.gpc.businessservice.factory.security.SecurityServiceFactory; import com.gpc.businessservice.interfaces.loyalty.LoyaltyProgramService; import com.gpc.client.common.ClientApplicationContext; import com.gpc.client.common.event.CustomerEvent; import com.gpc.client.common.event.CustomerListener; import com.gpc.client.common.event.InvoiceEvent; import com.gpc.client.common.event.InvoiceListener; import com.gpc.client.common.event.PaymentEvent; import com.gpc.client.common.event.PaymentListener; import com.gpc.client.common.event.PointOfSaleEventDispatcher; import com.gpc.client.common.event.PointOfSaleListEvent; import com.gpc.client.common.focusmanager.FocusDecider; import com.gpc.client.common.input.document.FwoValidatedDecimalNumberDocument; import com.gpc.client.common.input.document.FwoValidatedWholeNumberDocument; import com.gpc.client.common.input.document.TsoTextPersistedDateDocument; import com.gpc.client.common.input.verifier.FwoBaseInputVerifier; import com.gpc.client.common.input.verifier.FwoDateVerifier; import com.gpc.client.common.input.verifier.TsoSimpleTimeVerifier; import com.gpc.client.common.mvc.IView; import com.gpc.client.common.paymentcard.CreditUtils; import com.gpc.client.common.paymentcard.IntegratedPaymentProcessHelper; import com.gpc.client.common.paymentcard.PaymentCardDlg; import com.gpc.client.common.paymentcard.StoreCardTypes; import com.gpc.client.common.util.CashDrawer; import com.gpc.client.pointofsale.customer.CustomerBL; import com.gpc.client.pointofsale.giftcard.GiftCardBL; import com.gpc.client.pointofsale.invoice.line.InvoiceLineBL; import com.gpc.client.pointofsale.invoice.line.InvoiceListModel; import com.gpc.client.pointofsale.tax.Tax; import com.gpc.client.pointofsale.util.BaseController; import com.gpc.client.pointofsale.util.DefaultDocument; import com.gpc.client.pointofsale.util.TimeTextDocument; import com.gpc.client.pospricing.rmiclient.POSPricingClient; import com.gpc.common.ApplicationContext; import com.gpc.common.BOPISLogger; import com.gpc.common.Constants; import com.gpc.common.Profile; import com.gpc.common.ResourceBundleReader; import com.gpc.common.TsoConstant; import com.gpc.common.TsoCurrentUser; import com.gpc.common.constants.IntegratedPaymentCardConstants; import com.gpc.common.constants.PasswordConstants; import com.gpc.common.constants.giftcard.GiftCardConstants; import com.gpc.common.constants.loyalty.LoyaltyConstants; import com.gpc.common.constants.refvalues.RefBillingType; import com.gpc.common.constants.refvalues.RefCountry; import com.gpc.common.constants.refvalues.RefInvoiceLineItemType; import com.gpc.common.constants.refvalues.RefInvoiceNoteType; import com.gpc.common.constants.refvalues.RefLanguage; import com.gpc.common.constants.refvalues.RefLoyaltyCustomerStatus; import com.gpc.common.constants.refvalues.RefNAPACustomerCategory; import com.gpc.common.constants.refvalues.RefPhoneRoomInvoiceSetting; import com.gpc.common.constants.refvalues.RefRadsDiscrepancyType; import com.gpc.common.constants.refvalues.RefTenderType; import com.gpc.common.constants.refvalues.RefTenderTypeCategory; import com.gpc.common.enums.BREAction; import com.gpc.common.exception.ApplicationException; import com.gpc.common.exception.NoPaymentFoundException; import com.gpc.common.multistore.MSHelper; import com.gpc.common.pattern.FwoDatePattern; import com.gpc.common.pattern.FwoPattern; import com.gpc.common.pattern.FwoPhonePattern; import com.gpc.common.pattern.FwoTimePattern; import com.gpc.common.pattern.PatternFormatException; import com.gpc.common.pattern.PatternParseException; import com.gpc.common.pattern.PhonePatternFormatException; import com.gpc.common.paymentcard.IntegratedPaymentCardHelper; import com.gpc.common.pointofsale.invoice.CommonInvoiceBL; import com.gpc.common.pointofsale.invoice.line.CommonInvoiceLineBL; import com.gpc.common.util.FwoUtil; import com.gpc.common.util.MathUtil; import com.gpc.common.util.RefStoreConfigurationUtil; import com.gpc.common.util.ParameterizedStringParser; import com.gpc.common.util.StringUtils; import com.gpc.valueobjects.PointOfSaleVO; import com.gpc.valueobjects.cepdi.CEPDIStatusVO; import com.gpc.valueobjects.common.IDValuePairVO; import com.gpc.valueobjects.common.POSStateVO; import com.gpc.valueobjects.common.ServerInfoVO; import com.gpc.valueobjects.customer.CustomerBlanketPOVO; import com.gpc.valueobjects.customer.CustomerDeliveryVO; import com.gpc.valueobjects.customer.CustomerVO; import com.gpc.valueobjects.customer.DeliveryPriorityVO; import com.gpc.valueobjects.giftcard.GiftCardResponse; import com.gpc.valueobjects.hardware.PrinterVO; import com.gpc.valueobjects.invoice.CheckoutVO; import com.gpc.valueobjects.invoice.InvoiceDeliveryVO; import com.gpc.valueobjects.invoice.InvoicePaymentVO; import com.gpc.valueobjects.invoice.InvoiceVO; import com.gpc.valueobjects.invoice.SignatureVO; import com.gpc.valueobjects.invoice.TransportInvoiceInfoVO; import com.gpc.valueobjects.invoice.display.DisplayableInvoiceVO; import com.gpc.valueobjects.invoice.line.BaseLineItemVO; import com.gpc.valueobjects.invoice.line.InvoiceLineItemReturnVO; import com.gpc.valueobjects.invoice.line.InvoiceLineItemVO; import com.gpc.valueobjects.invoice.line.InvoiceNoteVO; import com.gpc.valueobjects.invoice.line.PhoneRoomStoreVO; import com.gpc.valueobjects.invoice.rads.RadsDiscrepancyLog; import com.gpc.valueobjects.loyalty.LoyaltyRequest; import com.gpc.valueobjects.loyalty.LoyaltyResponse; import com.gpc.valueobjects.loyalty.Message; import com.gpc.valueobjects.loyalty.TransactionIdentifier; import com.gpc.valueobjects.misc.TerminalVO; import com.gpc.valueobjects.ordering.notification.OrderNotificationStatus; import com.gpc.valueobjects.ordering.salesorder.SalesOrderRecipientAddressVO; import com.gpc.valueobjects.ordering.salesorder.SalesOrderVO; import com.gpc.valueobjects.paymentcard.IntegratedPaymentCardResponseDataDetail; import com.gpc.valueobjects.paymentcard.ResponseDataDetail; import com.gpc.valueobjects.profile.InvoicingProfileVO; import com.gpc.valueobjects.profile.StoreProfileVO; import com.gpc.valueobjects.profile.TenderTypeProfileVO; import com.gpc.valueobjects.reftables.RefTableVO; import com.gpc.valueobjects.report.FwoPrinterSelectionSettings; import com.gpc.valueobjects.tax.TaxTableVO; import com.gpc.client.pointofsale.tax.PhoneRoomTax; import com.gpc.client.pointofsale.invoice.line.PhoneRoomInvoiceLineBL; import com.gpc.client.pointofsale.customer.PhoneRoomCustomerBL; public abstract class FinalizeInvoiceBaseController extends BaseController implements InvoiceListener, PaymentListener, WindowListener, CustomerListener { protected static final Logger logger = Logger.getLogger(FinalizeInvoiceBaseController.class); protected static final BigDecimal BD_ZERO = new BigDecimal("0.00"); protected static final String DELIVERY_YES = TsoConstant.GENERIC_Y; protected static final String DELIVERY_NO = TsoConstant.GENERIC_N; protected static final int DISTANCE_CEPDI_TRANSPORT= TsoConstant.DISTANCE_CEPDI_TRANSPORT; protected static final int DEFAULT_DISTANCE_CEPDI_TRANSPORT = 0; protected static final String DELIVERY_EMPTY = ""; protected static final int DEFAULTPANEL = 0; protected static final int CASHPANEL = 1; protected static final int BOPISNAPAONLINEPANEL = 13; protected static final int CREDITCARDPANEL = 2; protected static final int CHARGEPANEL = 3; protected static final int CHECKPANEL = 4; protected static final int COUPONPANEL = 5; protected static final int DEBITCARDPANEL = 7; protected static final int GIFTCERTIFICATEPANEL = 8; protected static final int REFUNDPANEL = 9; protected static final int NAPA_GIFT_CARD_PANEL = 10; protected static final int INTEGRATEDPAYMENT = 11; protected static final int EASY_PAY_PANEL = 14; protected static final int ELECTRONIC_FUND_TRANSFER = 12; protected static final int DO_NOT_PROCEED = -1; protected static final int DO_NOT_BOTHER = 0; protected static final int SUCCESS = 1; protected static final int FAILED = 2; protected static final int MAXIMUM_ATTEMPTS = 2; protected final FinalizeBaseDialog finalizeBaseDialog; protected final JComponent glassPane; protected final PaymentController paymentController; protected final PasswordController passwordController; protected ExpressCheckoutController expressCheckoutController; protected final GiftCardController giftCardController; protected final InvoiceListModel invoiceListModel; protected TerminalVO terminalVO = null; protected InvoiceVO invoiceVO; protected InvoiceVO returnedInvVO; protected InvoiceVO originalInvoiceVo; protected DisplayableInvoiceVO dispInvVO; protected InvoiceDeliveryVO invoiceDeliveryVO; protected CustomerVO customerVO; protected CustomerDeliveryVO customerDeliveryVO; protected String deliveryFlag = "O"; protected BigDecimal bdInvoiceSubtotal = BD_ZERO; protected BigDecimal bdInvoiceTotal = BD_ZERO; protected BigDecimal bdAmtTendered = BD_ZERO; protected BigDecimal bdBalanceDue = BD_ZERO; protected CustomerBlanketPOVO blanketPO; protected int defaultPrinterID = -1; protected InvoicePaymentVO paymentVO = null; protected int paymentSelected = 0; protected String strProcessingForAuthorization; protected String strPostingAndPrintingInProgressMessage; protected String strPORequired; protected String strAttentionRequired; protected String strDeliveryRequired; protected String strMustSignReceipt; protected String strMustSignRefund; protected String strBlanketPOExpired; protected String strMustEnterDeliveryDate; protected String strMustEnterDeliveryTime; protected String strMustEnterDeliveryMethod; protected String strDeliveryMethod; protected String strNoPayMethod; protected String notAssigned; protected String okText; protected String printText; protected boolean skipMiscAdj = true; protected boolean skipTax = true; protected boolean skipPaymentMethod = false; protected boolean allowMiscAdj = true; protected boolean bUse24HrsTime = false; protected boolean actionInProgress = false; private long lastPrintInvoiceTime = 0L; protected POSPricingClient posPricingClient; protected Thread processingThread = null; protected AbstractFinalizeHandler finalizeHandler; protected Locale locale = null; protected boolean escapeKeyPressed = false; protected String defaultDelivery; protected boolean useAmPmRadios = true; /** The auto invoice. */ protected boolean autoInvoice = false; protected CheckoutVO checkoutVO = null; protected int defaultCustomerTaxId = 0; protected boolean invoiceFinalized = false; PhoneNumberController phoneNumberController; InvitationController invitationController; PhoneNumberDialog phoneNumberDialog; private boolean isStartTransactionSuccessful = false; LoyaltyProgramService loyaltyProgramService = null; LoyaltyRequest request = null; protected boolean isNapaRewardProgram = false; PaymentPanel payPanel; private String loyaltyCustomerExternalIdentifier; private Byte refLoyaltyCustomerStatusId; private String loyaltyCustomerLookup; private String loyaltyInvoiceExternalIdentifier; private boolean isLoyaltyRefund; List invoiceReturnItemsList = null; List originalInvoiceLineItemsList = null; List napaRewardsNonEligibleList = null; private BigDecimal alreadySentLoyaltyAmount = new BigDecimal(0); private BigDecimal rewardForReturn = new BigDecimal(0); private Vector invoiceLineItemsVector; private LoyaltyResponse memberStatusOrDeclineResponse; private Map returnHistory; private HashMap fullInvoiceWithRewardMap; private HashSet vendorIdentifierSet; private CustomerInfoController customerInfoController; private ValidatePickupPersonIdentityController validatePickupPersonIdentityController; protected boolean isBopisInvoice = false; private SalesOrderVO salesOrderVO = null; protected BigDecimal rewardsBopis = new BigDecimal(0.00); private boolean isNapaRewardsProgramVersion2Active = false; private boolean bopisPaymentFailed; private AllowRetryAndLocalFundingController allowRetryAndLocalFundingController; private int retryCounter = 3; TransportInvoiceInfoController transportInfoController=null; SignatureController signatureController=null; boolean isOk = false; TransportInvoiceInfoVO transportVO=null; private GiftCardPaymentErrorController giftCardPaymentErrorController; private GiftCardErrorController giftCardErrorController; TaapRouter taapRouter = new TaapRouter(); PhoneRoomTaapRouter phoneRoomTaapRouter = new PhoneRoomTaapRouter(); Vector storePaymentMethods = new Vector(); /** * To make all four controllers to use this method following methods * are used so that all controllers work. * * setCallerDialog : This method set dialog to PaymentController. * Current Regular and Optional controller is * setting dialog. Rest have empty implementation. * setExpressCheckoutController : This method initialises ExpressCheckoutController. * Current Phone room controller has empty * implementation. Rest use base class method. * * @param finalizeBaseDialog */ public FinalizeInvoiceBaseController(FinalizeBaseDialog finalizeBaseDialog) { invoiceVO = new InvoiceVO(); this.finalizeBaseDialog = finalizeBaseDialog; glassPane = (JComponent) finalizeBaseDialog.getGlassPane(); paymentController = new PaymentController(); setCallerDialog(finalizeBaseDialog); finalizeBaseDialog.getContentPane().add((PaymentPanel) paymentController.getView()); invoiceDeliveryVO = new InvoiceDeliveryVO(); passwordController = new PasswordController(finalizeBaseDialog); setExpressCheckoutController(finalizeBaseDialog); giftCardController = new GiftCardController(finalizeBaseDialog); invoiceListModel = new InvoiceListModel(); finalizeBaseDialog.lstPaymentsTendered.setModel(invoiceListModel); phoneNumberController = new PhoneNumberController(finalizeBaseDialog); invitationController = new InvitationController(finalizeBaseDialog); phoneNumberDialog = (PhoneNumberDialog) phoneNumberController .getView(); loyaltyProgramService = LoyaltyProgramServiceFactory.getLoyaltyProgramService(); customerInfoController = new CustomerInfoController(finalizeBaseDialog); payPanel = (PaymentPanel) paymentController.getView(); validatePickupPersonIdentityController = new ValidatePickupPersonIdentityController(finalizeBaseDialog); allowRetryAndLocalFundingController = new AllowRetryAndLocalFundingController(finalizeBaseDialog); giftCardPaymentErrorController = new GiftCardPaymentErrorController(finalizeBaseDialog); giftCardErrorController = new GiftCardErrorController(finalizeBaseDialog); checkFlagsAndSetButtons(); install(finalizeBaseDialog); localizeView(); } /** * This method initialises ExpressCheckoutController. Current Phone room * controller has empty implementation. Rest use base class method. * @param finalizeBaseDialog */ protected void setExpressCheckoutController( FinalizeBaseDialog finalizeBaseDialog) { expressCheckoutController = new ExpressCheckoutController(finalizeBaseDialog); } /** * This method checks whether charge payment method is available. * @return true if found. */ protected boolean isChargeInvoice() { boolean chargeInvoice = false; if ((invoiceListModel.getData() != null) && (invoiceListModel.getData().size() > 0)) { InvoicePaymentVO vo = (InvoicePaymentVO) invoiceListModel.getData().elementAt(0); if ((vo.getTenderTypeID() != null) && (vo.getTenderTypeID().intValue() == RefTenderType.CHARGE_ON_ACCOUNT)) { chargeInvoice = true; } } return chargeInvoice; } /** * This method enables button based on some flags. Due to the complexity of * implementing all four controllers code, the method is segregated into * following overloaded method. * * checkManualFlagAndSetButtons(boolean) : * This method enables button based on * manual invoice flag. Phone room * controller has its own implementation * of it. Rest all use base controller * method. * checkSpecificFlagsAndSetButtons(boolean, boolean) : * This method enables button based on * manual invoice flag and whether a * invoice has invoice number. Phone room * controller has its own implementation * of it. Rest all use base controller * method. * setSpecificButtons(boolean, boolean, boolean) : * This method enables button based on * manual invoice flag, whether a invoice * erasure allowed and whether it is a * void invoice. Phone room controller has * its own implementation. Rest all use * base controller method. * */ private void checkFlagsAndSetButtons() { boolean haveAnInvoiceNumber = false; if ((invoiceVO != null) && (invoiceVO.getInvoiceNumber() != null) && (invoiceVO.getInvoiceNumber().intValue() > 0)) { haveAnInvoiceNumber = true; } boolean manulTRX = false; if ((invoiceVO != null) && (invoiceVO.getManualTransaction().booleanValue())) { manulTRX = true; } checkSpecificFlagsAndSetButtons(haveAnInvoiceNumber, manulTRX); } /** * This method enables button based on manual invoice flag. Phone room * controller has its own implementation of it. Rest all use base * controller method. * @param isManual true if it is a manual invoice. */ protected void checkManualFlagAndSetButtons(boolean isManual) { // determine state of save button if (isManual || CustomerBL.isNapaOnlineCustomer(customerVO)) { finalizeBaseDialog.btnSaveInvoice.setEnabled(false); } else { finalizeBaseDialog.btnSaveInvoice .setEnabled(clientApplicationContext .getProfile(Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()) .getInvoicingProfile().getUseSaveInvoice() .booleanValue()); } finalizeBaseDialog.btnExpressCheckout.setEnabled(!isManual && InvoiceBL.allowExpressCheckout(isChargeInvoice())); // user *must* enter a tax amount if (isManual) { if (finalizeBaseDialog.fldTax1.getText() == null || finalizeBaseDialog.fldTax1.getText().equals("")) { if (!isForcePost()) { finalizeBaseDialog.btnPrint.setEnabled(false); } else { logger.debug("===>>> enable btnPrint here for manager approved force post"); finalizeBaseDialog.btnPrint.setEnabled(true); } } } } /** * This method enables button based on manual invoice flag and whether a * invoice has invoice number. Phone room controller has its own * implementation of it. Rest all use base controller method. To make all * four controllers to use this method following method is used so that * all controllers work. * * isAllowInvoiceErase : This method checks for allowInvoiceErase flag of * invoicing profile. Phone room controller pulls * this value from remote store. Rest all use base * controller method. * @param haveAnInvoiceNumber true if invoice have number * @param manulTRX true if manual transaction. */ protected void checkSpecificFlagsAndSetButtons(boolean haveAnInvoiceNumber, boolean manulTRX) { boolean isEraseAllowed = false; boolean isReturnToInvoiceAllowed = false; boolean allowErasureOfCashInvoices = isAllowInvoiceErase(); if ((customerVO != null) && (customerVO.getBillTypeCode() != null)) { if (customerVO.getBillTypeCode().equalsIgnoreCase(RefBillingType.CHARGE_ONLY)) { isEraseAllowed = true; isReturnToInvoiceAllowed = true; } if (customerVO.getBillTypeCode().equalsIgnoreCase(RefBillingType.CASH_ONLY)) { if (allowErasureOfCashInvoices) { isEraseAllowed = true; isReturnToInvoiceAllowed = true; } } if (customerVO.getBillTypeCode().equalsIgnoreCase(RefBillingType.CASH_OR_CHARGE)) { if (allowErasureOfCashInvoices) { isEraseAllowed = true; isReturnToInvoiceAllowed = true; } else { if ((invoiceListModel.getData() != null) && (invoiceListModel.getData().size() > 0)) { InvoicePaymentVO firstPayment = (InvoicePaymentVO) invoiceListModel .getData().elementAt(0); if ((firstPayment.getTenderTypeID() != null) && (firstPayment.getTenderTypeID().intValue() == RefTenderType.CHARGE_ON_ACCOUNT)) { isEraseAllowed = true; isReturnToInvoiceAllowed = true; } } } } } if ((haveAnInvoiceNumber) && (!manulTRX)) { finalizeBaseDialog.btnReturnToInvoice.setVisible(false); finalizeBaseDialog.btnReturnToInvoice.setEnabled(false); finalizeBaseDialog.btnSaveInvoice.setEnabled(false); setSpecificButtons(true, isEraseAllowed, manulTRX); } else { setSpecificButtons(false, isEraseAllowed, manulTRX); finalizeBaseDialog.btnReturnToInvoice.setVisible(true); finalizeBaseDialog.btnReturnToInvoice.setEnabled(isReturnToInvoiceAllowed || manulTRX); } } /** * This method enables button based on manual invoice flag, whether a invoice * erasure allowed and whether it is a void invoice. Phone room controller has * its own implementation. Rest all use base controller method. * * @param isVoid * @param isEraseAllowed * @param isManual */ protected void setSpecificButtons(boolean isVoid, boolean isEraseAllowed, boolean isManual) { finalizeBaseDialog.btnVoid.setVisible(isVoid); finalizeBaseDialog.btnVoid.setEnabled(isVoid); if (isVoid) { finalizeBaseDialog.btnErase.setEnabled(!isVoid); finalizeBaseDialog.btnExpressCheckout.setEnabled(!isVoid); } else { finalizeBaseDialog.btnErase.setEnabled(isEraseAllowed || isManual); checkManualFlagAndSetButtons(isManual); } if(isBopisInvoice){ finalizeBaseDialog.btnErase.setEnabled(false); } } /** * This method is called from the InvoiceLinePanel to pass invoice data to * the finalize dialog. To make all four controllers to use this method * following methods are used so that all controllers work. * * loadDeliveryComboBasedOnSettings : This method loads delivery combobox. * Phone room and Non phone room controller has implementation. Rest has * empty implementation. * * loadDataFromSpecificStore : This method loads data. Phone room * controller use this method to load * data from remote store. Rest all * use base class method to load data. * setOptionalDeliveryFlag : This method set optionalDeliveryFlag. * Only Optional controller has * implementation. Rest all use empty * implementation. * isDeliveryChecked : This method checks if delivery is * applied . All four controllers * implement this method. * resetCheckPanel : This method reset check panel of * Payment Controller. Current Phone * room controller has empty * implementation. Rest all use base * class method. * isPrinterPresent : This method check whether cbPrinter * has printer. Current Phone room * controller has its implementation. * Rest all use base class method. * delegateSetInitialData : This method prepares a thread. All * controller use base class method. * Only phone room has implementation * where it perform specific things * before calling base class method. * loadFinalizeHandler : This method loads FinalizeHandler. * Phone room and Non phone room * controller has specific * implementation. Res all use common * implementation. * @param newInvoiceVO * @param newDispInvVO * @return */ public boolean setInitialData(InvoiceVO newInvoiceVO, DisplayableInvoiceVO newDispInvVO) { escapeKeyPressed = false; resetValues(); clearList(); invoiceVO = newInvoiceVO; originalInvoiceVo = (InvoiceVO) invoiceVO.clone(); dispInvVO = newDispInvVO; processingThread = null; invoiceFinalized = false; isStartTransactionSuccessful = false; isNapaRewardProgram = false; isLoyaltyRefund = false; invoiceReturnItemsList = null; originalInvoiceLineItemsList = null; alreadySentLoyaltyAmount = new BigDecimal(0); rewardForReturn = new BigDecimal(0); invoiceLineItemsVector = null; memberStatusOrDeclineResponse = null; fullInvoiceWithRewardMap = null; vendorIdentifierSet = null; bopisPaymentFailed=false; logger.warn("init method started in FinalizeInvoiceBaseController**"); checkIfBopisInvoice(); paymentController.setAllowBopisPaymentValidation(true); if (isBopisInvoice) { finalizeBaseDialog.fldAttention.setDocument(new DefaultDocument( finalizeBaseDialog.fldAttention, clientApplicationContext.getSystemDAO().getAttentionCharLength().intValue(), DefaultDocument.ANY)); } else { finalizeBaseDialog.fldAttention .setDocument(new DefaultDocument( finalizeBaseDialog.fldAttention, clientApplicationContext.getSystemDAO() .getAttentionCharLength().intValue(), DefaultDocument.ALPHANUMERIC, new char[] { ',', '.', '-', ' ' })); } resetPanel(); loadDeliveryComboBasedOnSettings(); // set text on btnPrint if (invoiceVO.getManualTransaction().booleanValue()) { finalizeBaseDialog.pnlAlternateCoreSubtotal.setVisible(false); finalizeBaseDialog.btnPrint.setText(okText); } else { finalizeBaseDialog.pnlAlternateCoreSubtotal.setVisible(customerVO .getAlternateCoreCustomerID() != null); finalizeBaseDialog.btnPrint.setText(printText); } if (!loadDataFromSpecificStore()) { return false; } // call to display customer number, name and phone displayCustomerInfo(); if (!invoiceVO.getManualTransaction().booleanValue() && customerVO.getAlternateCoreCustomerID() != null) { final BigDecimal alternateCoreSubTotal = invoiceVO.getAlternateCoreSubTotal(); logger.debug("alternateCoreSubTotal = " + alternateCoreSubTotal); if (alternateCoreSubTotal == null || (alternateCoreSubTotal.compareTo(BD_ZERO) == 0)) { // The system should check to ensure that at the time of finalizing an order, // the alternate core subtotal matches the sum of core parts. final BigDecimal newAlternateCoreSubTotal = InvoiceBL .reCalculateAlternateCoreSubTotal(invoiceVO); logger.debug("calculatedAlternateCoreSubTotal = " + newAlternateCoreSubTotal); if (newAlternateCoreSubTotal != null && newAlternateCoreSubTotal.compareTo(BD_ZERO) != 0) { invoiceVO.setAlternateCoreSubTotal(newAlternateCoreSubTotal); } } finalizeBaseDialog.dlblAlternateCoreSubtotal.setText(invoiceVO .getAlternateCoreSubTotal().toString()); } // Add or remove Colorado Delivery Fee addOrRemoveColoradoDeliveryFeeLineItem(); bdInvoiceSubtotal = BD_ZERO; bdInvoiceSubtotal = bdInvoiceSubtotal.add(invoiceVO.getSubTotal()); bdInvoiceSubtotal = bdInvoiceSubtotal.setScale(2, BigDecimal.ROUND_HALF_UP); finalizeBaseDialog.dlblSubtotal.setText(bdInvoiceSubtotal.toString()); if (!loadDeliveryPriority()) { return false; } setOptionalDelivery(true); loadDeliveryDefaults(); if (isDeliveryChecked() && invoiceVO.getSavedInvoiceIdForDeletion() == null) { verifyForCustomerDeliveryTax(); } // loadBlanketPO(); // Load the previously stored delivery options if (invoiceVO.getInvoiceDeliveryVO() != null) { invoiceDeliveryVO = invoiceVO.getInvoiceDeliveryVO(); loadDeliveryInfo(); } loadAttentionAndPOInfo(); loadMiscAdjustment(); logger.debug("calling loadPaymentMethod"); loadPaymentMethod(); loadTaxInfo(); loadPrinters(); resetCheckPanel(); paymentController.refreshLists(); if (isPrinterPresent()) { finalizeBaseDialog.cbPrinter .setSelectedIndex(getPrinterIndex(defaultPrinterID)); } String chargeValue = finalizeBaseDialog.fldDeliveryCharge.getText(); if ((chargeValue == null) || (chargeValue.trim().length() == 0)) { finalizeBaseDialog.fldDeliveryCharge.setText("0.00"); finalizeBaseDialog.dlblDeliveryCharge.setText("0.00"); } // this calculate the taxable sales // TaxTableVO taxTableVO = new TaxTableVO(); //not used, only needed for // call /* * If customer has alt core don't include core items for tax * calculation. */ boolean includeCoreItems = (customerVO.getAlternateCoreCustomerID() == null) ? true : false; boolean includeDeliveryCharge = (clientApplicationContext.getApplicationType() == ClientApplicationContext.TAMS_II) ? true : false; if(invoiceVO!=null && invoiceVO.isPhoneRoomMessagesFlag()) { PhoneRoomTax.recalculateTaxableSales( invoiceVO, false, includeCoreItems, includeDeliveryCharge, Profile.POINT_OF_SALE_CLIENT, customerVO, getRemoteIPAddress()); }else { Tax.recalculateTaxableSales( invoiceVO, false, (customerVO.getAlternateCoreCustomerID() == null), clientApplicationContext.getApplicationType() == ClientApplicationContext.TAMS_II, Profile.POINT_OF_SALE_CLIENT, customerVO); } loadBopisRewards(); calculateInvoiceTotal(); Thread paymentThread = delegateSetInitialData(); if (customerVO.getMiscInvDiscountRefOptionCD() != null && customerVO.getMiscInvDiscountRefOptionCD().equalsIgnoreCase( "O")) { skipMiscAdj = false; } enablePanel(); // doing this here because enablePanel enables the payment fields. if (invoiceVO.getManualTransaction().booleanValue()) { finalizeBaseDialog.lstPaymentMethod.setEnabled(false); finalizeBaseDialog.sqfPaymentMethod.setEnabled(false); } InvoicingProfileVO invoicingProfileVO = null; if(null!=invoiceVO && invoiceVO.isPhoneRoomMessagesFlag()) { invoicingProfileVO = getRemoteInvoicingProfileVO(); } else { invoicingProfileVO = getInvoicingProfile(); } logger.debug("UseNapaRewards Flag: " + invoicingProfileVO.getUseNAPARewards().booleanValue()); decideAndPlaceFocus(); actionInProgress = false; loadFinalizeHandler(); isNapaRewardProgram = invoicingProfileVO.getUseNAPARewards().booleanValue() && !invoiceVO.getManualTransaction().booleanValue() && customerVO.getREFNAPACustomerCategoryID().intValue() == (RefNAPACustomerCategory.RETAIL_DIY) && !(clientApplicationContext.isLoggedInAsPhoneRoom() && (isPhoneRoomMessageCheckout() || isRemoteStore())) && !isBopisInvoice; isNapaRewardsProgramVersion2Active = loyaltyProgramService.doesNapaRewardProgramVersion2Active(); try { if(null!=invoiceVO && invoiceVO.isPhoneRoomMessagesFlag()){ napaRewardsNonEligibleList = new PhoneRoomTaapRouter().getLoyaltyNonEligibleList(clientApplicationContext.getLocation(),getRemoteIPAddress()); }else { napaRewardsNonEligibleList = clientApplicationContext .getInvoiceDAO().getNapaRewardsNonEligibleList(); } } catch (ApplicationException applicationException) { logger.error(applicationException.getMessage(), applicationException); } updateLoyaltyEligibleForLineItem(); if (isNapaRewardProgram) { Thread esbThread = delegateToESBRegistration(paymentThread); if (esbThread != null) { esbThread.start(); } } else { if (paymentThread != null) { paymentThread.start(); } } validatePersonIdentityForPickup(); logInvoiceDetails(); logger.warn("init method ended in FinalizeInvoiceBaseController**"); return true; } private void checkIfBopisInvoice() { isBopisInvoice = false; paymentController.isBopisInvoice(false); retryCounter = 3; Integer refOrderSubTypeId = null; if (invoiceVO != null && invoiceVO.getSalesOrderVO() != null && invoiceVO.getSalesOrderVO().getId() != null){ salesOrderVO = getSalesOrderVO(); if (salesOrderVO != null) { refOrderSubTypeId = salesOrderVO.getRefOrderSubTypeId(); if (refOrderSubTypeId != null && refOrderSubTypeId.intValue() == TsoConstant.NOL_BOPIS) { isBopisInvoice = Boolean.TRUE.booleanValue(); paymentController.isBopisInvoice(true); paymentController.setInvoiceVO(invoiceVO); paymentController.setSalesOrderVO(salesOrderVO); } else { return; } } else { return; } } } /*This method checks if it is a BOPIS order, sales order id of current invoice is retrieved*/ private void validatePersonIdentityForPickup() { if (salesOrderVO != null && isBopisInvoice) { Integer salesOrderId = salesOrderVO.getId(); delegateToValidateIdentity(salesOrderId); } else { return; } } protected void loadBopisRewards() { if(salesOrderVO != null && isBopisInvoice){ rewardsBopis = (salesOrderVO.getRewardDiscount() != null) ? salesOrderVO.getRewardDiscount() : BD_ZERO ; if (rewardsBopis != null && rewardsBopis.intValue() != 0) { removeRewardLineItemIfExists(); BaseLineItemVO bliVO = null; Vector lineItems = invoiceVO.getLineItems(); bliVO = InvoiceLineBL.createLineItemForRewards(invoiceVO, customerVO, rewardsBopis.abs(), new BigDecimal("-1.00")); lineItems.add(bliVO); } invoiceVO.setRewardAmount(rewardsBopis.abs().negate().setScale(2,BigDecimal.ROUND_HALF_UP)); logger.error("FinalizeInvoiceBaseController:loadBopisRewards: Reward Amount is: "+invoiceVO.getRewardAmount()+" for Bopis Order Number: "+salesOrderVO.getNolOrderNumber()); finalizeBaseDialog.dlblRewards.setText(rewardsBopis.abs().negate().setScale(2,BigDecimal.ROUND_HALF_UP).toString()); } } /*This thread displays the customer verification dialog in order to validate pickup person identity for a BOPIS order*/ private void delegateToValidateIdentity(final Integer salesOrderId) { new Thread() { public void run() { /* * This is an existing design used by TAMSII code to use join when showing dialog on * top of dialog. This will provide enough time for swing to redirect focus to top * window. */ try { join(120); } catch (InterruptedException ee) { logger.debug(ee.getMessage(), ee); } try { SwingUtilities.invokeAndWait(new Runnable() { public void run() { /* * Call is embedded into a Thread as this call will display dialog on * top of 'Checkout' screen. There is always a possibility of focus * problem when multiple screen overlap each other. Call inside thread * will almost kill that possibility. */ ValidatePickupPersonIdentityDialog validatePickupPersonIdentityDialog = (ValidatePickupPersonIdentityDialog) validatePickupPersonIdentityController .getView(); validatePickupPersonIdentityController.disableEditing(true); try { //STEL-890 if(null!=invoiceVO && invoiceVO.isPhoneRoomMessagesFlag()){ String remoteIpAddress = getRemoteIPAddress(); List addressList = new TaapRouter().retrieveSalesOrderRecipientAddressBySalesOrderId(remoteIpAddress,salesOrderId); if (addressList.size() != 0) { if (addressList.size() > 1) { SalesOrderRecipientAddressVO authorizedRecipient1 = addressList.get(0); SalesOrderRecipientAddressVO authorizedRecipient2 = addressList.get(1); validatePickupPersonIdentityDialog.fldCustFullName .setText(authorizedRecipient1.getFullName()); validatePickupPersonIdentityDialog.fldAlternateName .setText(authorizedRecipient2.getFullName()); } else { SalesOrderRecipientAddressVO authorizedRecipient1 = addressList.get(0); validatePickupPersonIdentityDialog.fldCustFullName .setText(authorizedRecipient1.getFullName()); } } } else { List salesOrderRecipientAddressList = new ArrayList(); salesOrderRecipientAddressList = clientApplicationContext.getOrderingDAO() .getSalesOrderRecipientAddressBySalesOrderId(salesOrderId); if (salesOrderRecipientAddressList.size() != 0) { if (salesOrderRecipientAddressList.size() > 1) { SalesOrderRecipientAddressVO authorizedRecipient1 = (SalesOrderRecipientAddressVO) salesOrderRecipientAddressList .get(0); SalesOrderRecipientAddressVO authorizedRecipient2 = (SalesOrderRecipientAddressVO) salesOrderRecipientAddressList .get(1); validatePickupPersonIdentityDialog.fldCustFullName .setText(authorizedRecipient1.getFullName()); validatePickupPersonIdentityDialog.fldAlternateName .setText(authorizedRecipient2.getFullName()); } else { SalesOrderRecipientAddressVO authorizedRecipient1 = (SalesOrderRecipientAddressVO) salesOrderRecipientAddressList .get(0); validatePickupPersonIdentityDialog.fldCustFullName .setText(authorizedRecipient1.getFullName()); } } } } catch (ApplicationException e) { e.printStackTrace(); } int validatePickupPersonDialogAction = validatePickupPersonIdentityController .show(); logger.debug("action " + validatePickupPersonDialogAction); if (validatePickupPersonDialogAction == ValidatePickupPersonIdentityController.OK) { validatePickupPersonIdentityDialog.fldCustFullName .setText(""); validatePickupPersonIdentityDialog.fldAlternateName .setText(""); payPanel.btnSubmit.requestFocus(); return; } else if (validatePickupPersonDialogAction == ValidatePickupPersonIdentityController.CANCEL) { validatePickupPersonIdentityDialog.fldCustFullName.setText(""); validatePickupPersonIdentityDialog.fldAlternateName.setText(""); SwingUtilities.invokeLater(new Runnable() { public void run() { pointOfSaleEventDispatcher .fireInvoiceSaved(new InvoiceEvent(this, new InvoiceVO())); if (clientApplicationContext.getPOSState().getState() == POSStateVO.CASHIER) { pointOfSaleEventDispatcher.fireChangedToCashier(null); } finalizeBaseDialog.btnReturnToInvoice .dispatchEvent(pressTabKey(finalizeBaseDialog)); finalizeBaseDialog.setVisible(false); invoiceVO.setLineItems(null); isBopisInvoice = false; paymentController.isBopisInvoice(false); } }); } } }); } catch (InterruptedException interruptedException) { logger.error(interruptedException.getMessage(), interruptedException); } catch (InvocationTargetException invocationTargetException) { logger.error(invocationTargetException.getMessage(), invocationTargetException); } } }.start(); } /** * This method checks if the PhoneRoom checkout screen is Message or not * @return true if PhoneRoom message checkout screen. */ private boolean isPhoneRoomMessageCheckout(){ boolean phoneRoomMessage = false; try { boolean isRemoteStore = isRemoteStore(); final PhoneRoomStoreVO phoneRoomStoreVO = clientApplicationContext .getRemoteInvoiceDAO().getPhoneRoomInvoiceSetting( invoiceVO.getRemoteStoreNumber(), isRemoteStore); if (phoneRoomStoreVO != null) { if (phoneRoomStoreVO.getPhoneRoomInvoiceSettingId() == RefPhoneRoomInvoiceSetting.MESSAGE) { phoneRoomMessage = true; } } } catch (ApplicationException ae) { logger.error(ae.toString(), ae); } return phoneRoomMessage; } /** * This method checks if the logged in store is not a current store. * @return true if logged in store is remote store. */ private boolean isRemoteStore(){ String currentStoreNumber = clientApplicationContext .getProfile(Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()) .getStoreProfile().getStoreNum(); boolean isRemoteStore = true; if (invoiceVO.getRemoteStoreNumber() != null && invoiceVO.getRemoteStoreNumber().equals( currentStoreNumber)) { isRemoteStore = false; } return isRemoteStore; } /** * This method loads data. Phone room controller use this method to load * data from remote store. Rest all use base class method to load data. * @return true if exception does not occur. */ protected boolean loadDataFromSpecificStore() { boolean isDataLoaded = true; try { customerDeliveryVO = clientApplicationContext.getCustomerDAO() .getCustomerDelivery(loc, customerVO.getID(), customerVO.getCustomerTypeCD()); } catch (ApplicationException ae) { actionInProgress = false; logger.error(ae.toString(), ae); clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, ae.getUserMessageID(), ae.getUserMessageParameters()); logger.error("Error from TAMS Service programs. " + "Operation did not complete. " + "Please Contact TAMS Support. Service Error = " + ae.getUserMessageID()); isDataLoaded = false; } return isDataLoaded; } /** * This method reset check panel of Payment Controller. Current * Phone room controller has empty implementation. Rest all use * base class method. */ protected void resetCheckPanel() { paymentController.resetCheckPanel(); } /** * This method check whether cbPrinter has printer. Current * Phone room controller has its implementation. Rest all * use base class method. * @return true if cbPrinter contain printer. */ protected boolean isPrinterPresent() { return true; } /** * This method clears components. */ private void clearList() { finalizeBaseDialog.lstPaymentsTendered.clearSelection(); finalizeBaseDialog.lstPaymentsTendered.setListData(new Vector()); } /** * This method loads Attention and PO Number. */ private void loadAttentionAndPOInfo() { if (invoiceVO.getAttention() != null) { finalizeBaseDialog.fldAttention.setText(invoiceVO.getAttention()); } if (invoiceVO.getPONumber() != null) { String s = invoiceVO.getPONumber(); int index = findPOInComboBox(s); if (index > -1) { finalizeBaseDialog.cbPONumber.setSelectedIndex(index); } else { ((JTextField) finalizeBaseDialog.cbPONumber.getEditor() .getEditorComponent()).setText(invoiceVO.getPONumber()); } } } /** * This method loads the stored delivery information to the delivery option * panel.To make all four controllers to use this method following method * is used so that all controllers work. * * setDelivery : This method set the delivery component for each * controller. This is used since three types of UI * component is used for delivery among all controllers. * loadDeliveryInfo : This method select AM or PM radio button hour of day. * Current Regular and Optional checkout controller implement this method. * Rest has empty implementation. */ private void loadDeliveryInfo() { logger.debug("loadDeliveryInfo()"); if (invoiceVO.getDeliveryFlag() != null && invoiceVO.getDeliveryFlag().booleanValue()) { setDelivery(true); BigDecimal deliveryCharge = BD_ZERO; if (invoiceVO.getDeliveryCharge() != null) { deliveryCharge = invoiceVO.getDeliveryCharge(); } finalizeBaseDialog.fldDeliveryCharge.setText(deliveryCharge .toString()); finalizeBaseDialog.dlblDeliveryCharge.setText(deliveryCharge .toString()); if (invoiceDeliveryVO.getRequestedDeliveryDate() == null) { finalizeBaseDialog.rbDeliveryPriority.setSelected(true); int deliveryPriorityIndex = findDeliveryPriorityIndex(invoiceDeliveryVO .getDeliveryPriorityID()); if (deliveryPriorityIndex == 0 || deliveryPriorityIndex == -1) { finalizeBaseDialog.cbDeliveryPriority.setSelectedIndex(0); } else { finalizeBaseDialog.cbDeliveryPriority .setSelectedIndex(deliveryPriorityIndex); } } else { finalizeBaseDialog.rbDeliveryTime.setSelected(true); Date requestedDeliveryDate = invoiceDeliveryVO .getRequestedDeliveryDate(); FwoPattern datePattern = FwoPattern.getDatePatternInstance( clientApplicationContext.getCurrentLocale(), new Integer(clientApplicationContext .getProfile(Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()) .getStoreProfile().getRefDateFormatId() .intValue())); try { finalizeBaseDialog.fldDeliveryDate.setText(datePattern .format(requestedDeliveryDate)); FwoPattern timePattern = FwoPattern .getTimePatternInstance(clientApplicationContext .getCurrentLocale()); if (useMilitaryTime() && requestedDeliveryDate != null) { Calendar calendar = Calendar .getInstance(clientApplicationContext .getCurrentLocale()); calendar.setTime(requestedDeliveryDate); finalizeBaseDialog.fldDeliveryTime.setText(calendar .get(Calendar.HOUR_OF_DAY) + " : " + calendar.get(Calendar.MINUTE)); } else { finalizeBaseDialog.fldDeliveryTime.setText(timePattern .format(requestedDeliveryDate)); } loadDeliveryInfo(requestedDeliveryDate); } catch (PatternFormatException patternFormatException) { logger.error(patternFormatException.toString(), patternFormatException); try { finalizeBaseDialog.fldDeliveryDate.setText(datePattern .format(new Date())); } catch (PatternFormatException pfe) { logger.error(pfe.toString(), pfe); } } } if (invoiceDeliveryVO.getDeliveryDescription() != null) { finalizeBaseDialog.fldDeliveryMethod.setText(invoiceDeliveryVO .getDeliveryDescription()); } } } /** * This method gets the delivery priority index for the delivery * priority id. * * @param deliveryPriorityId delivery priority id * @return index of the delivery priority id in the combo box. */ private int findDeliveryPriorityIndex(Byte deliveryPriorityId) { int index = -1; int numOfItems = finalizeBaseDialog.cbDeliveryPriority.getItemCount(); if (deliveryPriorityId == null || numOfItems == 0) { return index; } Object object = null; IDValuePairVO item = null; logger.debug("numOfItems-->" + numOfItems); for (int i = 0; i < numOfItems; i++) { object = finalizeBaseDialog.cbDeliveryPriority.getItemAt(i); if (object instanceof IDValuePairVO) { item = (IDValuePairVO) object; if (item.getID() == null || ((item.getID() instanceof String && ((String) item .getID()).trim().equals("")))) { continue; } if (item.getID() instanceof Integer && ((Integer) item.getID()).intValue() == deliveryPriorityId .intValue()) { index = i; break; } } } return index; } /** * This method returns the index of PO in combo box * @param s the PO Number * @return index of cbPONumber */ private int findPOInComboBox(String s) { int index = -1; int numItems = finalizeBaseDialog.cbPONumber.getItemCount(); if (numItems == 0) { return index; } Object o = null; CustomerBlanketPOVO item = null; for (int i = 0; i < numItems; i++) { o = finalizeBaseDialog.cbPONumber.getItemAt(i); if ((o == null) || (!(o instanceof CustomerBlanketPOVO))) { continue; } item = (CustomerBlanketPOVO) o; if ((item.toString() == null) || !(item.toString().equals(s))) { continue; } index = i; } return index; } /** * This method loads the Delivery Priority list. Insert text "Not Assigned" * into the first item spot. To make all four controllers to use this * method following methods are used so that all controllers work. * * getDeliveryPriorities : This method retrieves the delivery priorities. * Phone room controller implement this method to * load from remote store. Rest all use base * controller method. * @return true if successful */ private boolean loadDeliveryPriority() { boolean zeroDefined = false; Vector vDeliveryPriorityList = null; try { vDeliveryPriorityList = getDeliveryPriorities(); } catch (ApplicationException ae) { logger.error(ae.toString(), ae); clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, ae.getUserMessageID(), ae.getUserMessageParameters()); return false; } if (finalizeBaseDialog.cbDeliveryPriority.getItemCount() > 0) { finalizeBaseDialog.cbDeliveryPriority.removeAllItems(); } if(vDeliveryPriorityList != null){ for (int i = 0; i < vDeliveryPriorityList.size(); i++) { DeliveryPriorityVO deliveryPriorityVO = (DeliveryPriorityVO) vDeliveryPriorityList .elementAt(i); /** * @todo: localization of "Minutes" */ logger.debug("--- loadDeliveryPriority, id= " + deliveryPriorityVO.getID().toString() + " minsForDelivery= " + deliveryPriorityVO.getNumMinutesForDelivery()); if (deliveryPriorityVO.getID().intValue() == 0) { logger.debug("--- zero is defined in priority list."); zeroDefined = true; } finalizeBaseDialog.cbDeliveryPriority.addItem(new IDValuePairVO( deliveryPriorityVO.getID(), deliveryPriorityVO.getName()+ " " + deliveryPriorityVO .getNumMinutesForDelivery() + " Minutes")); } } if (clientApplicationContext.getSystemDAO().isNotAssignedNull() .booleanValue()) { logger.debug("--- loadDeliveryPriority, isNotAssignedNull is true"); finalizeBaseDialog.cbDeliveryPriority.insertItemAt( new IDValuePairVO("", notAssigned), 0); finalizeBaseDialog.cbDeliveryPriority.setSelectedIndex(0); } else { if (!zeroDefined) { finalizeBaseDialog.cbDeliveryPriority.insertItemAt( new IDValuePairVO(new Integer(0), "0 " + notAssigned), 0); finalizeBaseDialog.cbDeliveryPriority.setSelectedIndex(0); } } finalizeBaseDialog.cbDeliveryPriority.setSelectedIndex(0); return true; } /** * This method selects primary tax based on customer delivery tax table. */ private void verifyForCustomerDeliveryTax() { if (customerVO.getDeliveredTaxTableID() == null) { return; } int deliveryTaxID = customerVO.getDeliveredTaxTableID().intValue(); if (deliveryTaxID < 0) { return; } selectPrimaryTax(deliveryTaxID); } /** * This method reset primary tax based on customer primary tax table. */ private void resetPrimaryTax() { TaxTableVO taxVO = customerVO.getPrimaryTaxTable(); if ((taxVO == null) || (taxVO.getID() == null) || (taxVO.getID().intValue() < 0)) { return; } selectPrimaryTax(taxVO.getID().intValue()); } /** * This method selects tax table in cbTax1. * @param taxID id from customer tax table. */ private void selectPrimaryTax(int taxID) { if (taxID < 0) { return; } int numOfItems = finalizeBaseDialog.cbTax1.getItemCount(); Object o = null; IDValuePairVO item = null; for (int i = 0; i < numOfItems; i++) { o = finalizeBaseDialog.cbTax1.getItemAt(i); if ((o == null) || (!(o instanceof IDValuePairVO))) { continue; } item = (IDValuePairVO) o; Short id = (Short) item.getID(); if ((id == null) || (id.intValue() != taxID)) { continue; } finalizeBaseDialog.cbTax1.setSelectedIndex(i); break; } } /** * This method loads the Tax1 combo list and if there is an associated * secondary tax display it. To make all four controllers to use this * method following methods are used so that all controllers work. * * getTaxTables : This method loads tax tables. * Phone room controller override this * method to load tax table from phone * room. Rest all use base controller * method. * isDeliveryChecked : This method checks if delivery is * applied . All four controllers * implement this method. * setDefaultCustomerTaxId : This method set defaultCustomerTaxId * variable. Only Optional controller * implement this method. Rest all use * empty implementation. * setTaxTableOfOriginalInvoiceVO : This method set tax table information. * Only phone room controller override * this method. Rest all use empty * implementation. */ private void loadTaxInfo() { Vector vTaxList = getTaxTables(); int defaultIndex = 0; String description = ""; Object value = null; int defaultTaxID = -1; if (isDeliveryChecked() && (customerVO.getDeliveredTaxTableID() != null) && invoiceVO.getSavedInvoiceIdForDeletion() == null) { defaultTaxID = customerVO.getDeliveredTaxTableID().intValue(); } if (defaultTaxID == -1) { // defaultTaxID is still not set, let's try to // set it to primary tax table id from // invoiceVO defaultTaxID = (invoiceVO.getPrimaryTaxTableID() == null || invoiceVO .getPrimaryTaxTableID().shortValue() < 1) ? -1 : invoiceVO .getPrimaryTaxTableID().intValue(); } if (vTaxList == null) { vTaxList = new Vector(); } /** * We have to rebuild the primary tax combo box each time when we visit * the check-out screen. The reson behind doing so is to get the latest * info from tax table everytime we comin here. * */ if (finalizeBaseDialog.cbTax1.getItemCount() > 0) { finalizeBaseDialog.cbTax1.removeAllItems(); } // Temporarily remove action listener unitl we build the comboBox. finalizeBaseDialog.cbTax1.removeActionListener(this); TaxTableVO manualInvTaxVO = null; // load the combo box for tax 1, the primary tax table String taxDesc = null; String taxPercent = null; for (int i = 0; i < vTaxList.size(); i++) { TaxTableVO taxTableVO = (TaxTableVO) vTaxList.elementAt(i); value = taxTableVO.getID(); taxDesc = taxTableVO.getDescription() == null ? "" : taxTableVO .getDescription(); taxPercent = taxTableVO.getSalesTaxPercent() == null ? "0" : taxTableVO.getSalesTaxPercent().toString(); description = value.toString() + ", '" + taxDesc + "', " + taxPercent + " %"; finalizeBaseDialog.cbTax1.addItem(new IDValuePairVO(value, description)); if (taxTableVO.getID().intValue() == defaultTaxID) { if (invoiceVO.getManualTransaction().booleanValue()) { manualInvTaxVO = taxTableVO; } defaultIndex = i; setDefaultCustomerTaxId(i); } } TaxTableVO taxTableVO = null; if (invoiceVO.getManualTransaction().booleanValue()) { taxTableVO = manualInvTaxVO; } // set the combobox to the default tax table, even for manula invoices if (finalizeBaseDialog.cbTax1.getItemCount() > 0) { if (finalizeBaseDialog.cbTax1.getSelectedIndex() != defaultIndex) { finalizeBaseDialog.cbTax1.setSelectedIndex(defaultIndex); processCbTax1(); } // get the description for the default tax percent. taxTableVO = (TaxTableVO) vTaxList.elementAt(defaultIndex); } // Put the actionListener back finalizeBaseDialog.cbTax1.addActionListener(this); if (taxTableVO == null) { taxTableVO = new TaxTableVO(); } // for manual invoices, the tax entry field is blank finalizeBaseDialog.fldTax1.setText(""); // we need to remember the selected table to check against if tax is // changed. if (invoiceVO.getManualTransaction().booleanValue()) { invoiceVO.setPrimaryTaxTableVO(manualInvTaxVO); } else { invoiceVO.setPrimaryTaxTableVO(taxTableVO); setTaxTableOfOriginalInvoiceVO(taxTableVO, true); } if (invoiceVO.getManualTransaction().booleanValue()) { finalizeBaseDialog.lstPaymentMethod.setEnabled(false); finalizeBaseDialog.sqfPaymentMethod.setEnabled(false); } // ********* // now find the secondary tax, if there is one, load the the tax percent // and description. int secTaxID = 0; if (taxTableVO != null && taxTableVO.getID().shortValue() > 0) { enableTax1(true); } else { finalizeBaseDialog.cbTax1.removeAllItems(); finalizeBaseDialog.dlblTax2.setText(""); finalizeBaseDialog.dlblTax2Amount.setText("0.00"); enableTax1(false); enableTax2(false); return; } if (taxTableVO.getSecondaryTaxTableID() == null || taxTableVO.getSecondaryTaxTableID().intValue() == 0) { finalizeBaseDialog.dlblTax2.setText(""); finalizeBaseDialog.dlblTax2Amount.setText("0.00"); enableTax2(false); return; } else { secTaxID = taxTableVO.getSecondaryTaxTableID().intValue(); enableTax2(true); } if (secTaxID != 0) { for (int i = 0; i < vTaxList.size(); i++) { taxTableVO = (TaxTableVO) vTaxList.elementAt(i); if (secTaxID == taxTableVO.getID().intValue()) { break; } } if (invoiceVO.getManualTransaction().booleanValue()) { finalizeBaseDialog.fldTax2.setText(invoiceVO.getTaxAmount2() .toString()); } else { // save secondary table to pick up any changes (such as tax // brackets) invoiceVO.setSecondaryTaxTableVO(taxTableVO); setTaxTableOfOriginalInvoiceVO(taxTableVO, false); finalizeBaseDialog.dlblTax2.setText("" + secTaxID + ", " + taxTableVO.getDescription() + " " + taxTableVO.getSalesTaxPercent().toString() + " %"); } } } /** * This method loads tax tables. Phone room controller override this * method to load tax table from phone room. Rest all use base * controller method. * @return */ protected Vector getTaxTables() { return clientApplicationContext.getSystemDAO().getTaxTables(); } /** * This method loads payment method. To make all four controllers to use * this method following methods are used so that all controllers work. * * getPaymentTypeList : This method loads tender type * based on customer Napa Online * flag. Current Phone room * controller implement it to * pull data from remote store. * Rest all use base class method. * setIntegratedPaymentVariables : This method set Integrated * payment variables. Only Regular * and Optional controller has * implementation of this method. * Rest all use empty * implementation. * getUseTenderTypes : This method checks use tender * type flag. Current Phone room * controller implement it to pull * data from remote store. Rest all * use base class method. * isPaymentRelatedToIPC : This method checks for payment * type. Only Regular and Optional * controller has implementation of * this method. Rest all return * 'false'. * isPaymentCardAllowedInPaymentMethod : This method checks whether * payment card is allowed in * payment method. Only Regular * and Optional controller has * implementation of this method. * Rest all return 'false'. */ private void loadPaymentMethod() { final String methodSpec = "FinalizeInvoiceBaseController.loadPaymentMethod - "; logger.debug(methodSpec); Locale applicationLocale = clientApplicationContext.getCurrentLocale(); boolean first = true; TenderTypeProfileVO fuelManCardProfile = null; TenderTypeProfileVO voyagerCardProfile = null; TenderTypeProfileVO wrightExpressCardProfile = null; String storeLanguageCd = null; String storeCountryCd = null; if (invoiceVO!=null && invoiceVO.isPhoneRoomMessagesFlag()) { fuelManCardProfile = taapRouter.getTenderTypeProfile(getRemoteIPAddress(), RefTenderType.FUEL_MAN_CARD); voyagerCardProfile = taapRouter.getTenderTypeProfile(getRemoteIPAddress(), RefTenderType.VOYAGER_CARD); wrightExpressCardProfile = taapRouter.getTenderTypeProfile(getRemoteIPAddress(), RefTenderType.WRIGHT_EXPRESS_CARD); storeLanguageCd = getStoreProfile().getRefLanguageCd(); storeCountryCd = getStoreProfile().getRefCountryCd(); }else { Profile profile = clientApplicationContext.getProfile( Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()); fuelManCardProfile = profile .getTenderTypeProfile(RefTenderType.FUEL_MAN_CARD); voyagerCardProfile = profile .getTenderTypeProfile(RefTenderType.VOYAGER_CARD); wrightExpressCardProfile = profile .getTenderTypeProfile(RefTenderType.WRIGHT_EXPRESS_CARD); storeLanguageCd = clientApplicationContext .getProfile(Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()) .getStoreProfile().getRefLanguageCd(); storeCountryCd = clientApplicationContext .getProfile(Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()) .getStoreProfile().getRefCountryCd(); } byte fuelManCardAccepted = fuelManCardProfile.getTenderTypeAccepted() .byteValue(); byte voyagerCardAccepted = voyagerCardProfile.getTenderTypeAccepted() .byteValue(); byte wrightExpressCardAccepted = wrightExpressCardProfile .getTenderTypeAccepted().byteValue(); final IntegratedPaymentCardHelper ipcHelper = IntegratedPaymentCardHelper .getInstance(); boolean isIPCEnabled = ipcHelper.isEnabled( Profile.POINT_OF_SALE_CLIENT, loc.intValue()); Locale storeLocale = new Locale(storeLanguageCd.toLowerCase(), storeCountryCd); InvoicingProfileVO invoicingProfileVO = null; if(null!=invoiceVO && invoiceVO.isPhoneRoomMessagesFlag()) { invoicingProfileVO = getRemoteInvoicingProfileVO(); } else { invoicingProfileVO = getInvoicingProfile(); } if (applicationLocale == null) { applicationLocale = Locale.getDefault(); } Vector vData = new Vector(); setWaitCursor(true); boolean isNapaOnlineCustomer = CustomerBL .isNapaOnlineCustomer(customerVO); Vector vPaymentTypeList = getPaymentTypeList(isNapaOnlineCustomer, applicationLocale); boolean paymentCardExist = false; if(vPaymentTypeList != null){ if (isNapaOnlineCustomer) { logger.debug("loading payment method list for NAPA Online customer"); // set payment method to cash // load the table with cash and the amount // this is the same as how we treat a charge customer. for (int i = 0; i < vPaymentTypeList.size(); i++) { RefTableVO refTableVO = (RefTableVO) vPaymentTypeList .elementAt(i); if ((refTableVO.getID().byteValue() == RefTenderTypeCategory.CASH)) { logger.debug(" adding cash to payment list"); vData.add(new IDValuePairVO(refTableVO.getID(), refTableVO .getDescription())); } } } else if(InvoiceBL.doesInvoiceContainCSGRestrictedReturnItem(invoiceVO)){ int tenderTypeCategory = InvoiceBL .retrieveCSGReturnItemOriginalInvoiceTenderTypeCategory(invoiceVO); logger.debug(methodSpec + "Original Invoice TenderTypeCategory = " + tenderTypeCategory); final Vector paymentTypeCategoryList = clientApplicationContext.getRefTableDAO() .getTenderTypeCatList(clientApplicationContext.getLocation(), applicationLocale.getLanguage()); final int paymentTypeListSize = paymentTypeCategoryList.size(); for (int index = 0; index < paymentTypeListSize; index++) { RefTableVO refTableVO = (RefTableVO) paymentTypeCategoryList.elementAt(index); if (refTableVO.getID().byteValue() == tenderTypeCategory) { vData.add(new IDValuePairVO(refTableVO.getID(), refTableVO.getDescription())); } if (customerVO.getBillTypeCode().equals(RefBillingType.CHARGE_ONLY) && tenderTypeCategory == RefTenderTypeCategory.CASH && refTableVO.getID().byteValue() == RefTenderTypeCategory.CHARGE_ON_ACCOUNT) { vData.add(new IDValuePairVO(refTableVO.getID(), refTableVO.getDescription())); } } } else { setIntegratedPaymentVariables(); for (int i = 0; i < vPaymentTypeList.size(); i++) { RefTableVO refTableVO = (RefTableVO) vPaymentTypeList.elementAt(i); byte refTableID = refTableVO.getID().byteValue(); if (customerVO.getBillTypeCode().equals( RefBillingType.CHARGE_ONLY) && (refTableID != RefTenderTypeCategory.CHARGE_ON_ACCOUNT)) { continue; } // if Other tender types are not allowed, cash and Charge are // the // only valid options if (!getUseTenderTypes() && (refTableID != RefTenderTypeCategory.CASH) && (refTableID != RefTenderTypeCategory.CHARGE_ON_ACCOUNT)) { continue; } if ((bdInvoiceSubtotal.doubleValue() < 0.0) && ((refTableID == RefTenderTypeCategory.COUPON) || (refTableID == RefTenderTypeCategory.GIFT_CERTIFICATE))) { continue; } // Check & EFT tender types are not allowed when invoice amount is less than or // equal to zero. if ((bdInvoiceSubtotal.doubleValue() <= 0.0) && ((refTableID == RefTenderTypeCategory.CHECK) || (refTableID == RefTenderTypeCategory.ELECTRONIC_FUND_TRANSFER))) { continue; } if ((bdInvoiceSubtotal.doubleValue() == 0.0) && ((refTableID == RefTenderTypeCategory.NAPA_GIFT_CARD))) { continue; } if ((isPaymentRelatedToIPC(refTableID) && !invoiceVO.getManualTransaction().booleanValue())) { if (isPaymentCardAllowedInPaymentMethod()) { if (first) { vData.add(new IDValuePairVO( new Short( (short) RefTenderTypeCategory.CREDIT_CARD), StoreCardTypes .getInstance() .getLocalizedPaymentCardDescription())); first = false; } continue; } else if (paymentController.integratedPaymentEnabled) { // Don't add Payment Card as a payment method if // terminal // doesn't have a PIN pad attached to it but the store // sets // IPC in use. continue; } } if (refTableID == RefTenderTypeCategory.CREDIT_CARD) { paymentCardExist = true; } vData.add(new IDValuePairVO(refTableVO.getID(), refTableVO .getDescription())); } if (!customerVO.getBillTypeCode().equals(RefBillingType.CHARGE_ONLY) && isIPCEnabled && getUseTenderTypes() && !(clientApplicationContext.isLoggedInAsPhoneRoom() && isRemoteStore()) && (isFleetCardAccepted(fuelManCardAccepted) || isFleetCardAccepted(voyagerCardAccepted) || isFleetCardAccepted(wrightExpressCardAccepted))) { vData.add(new IDValuePairVO(new Short((short) RefTenderTypeCategory.FLEET_CARD), clientApplicationContext .getResourceBundleReader().getLocalizedText( ResourceBundleReader.UI, getDialogName() + ".fleetCard", storeLocale))); } } } addEasyPayCardToVDataIfEnabled(applicationLocale, vData); finalizeBaseDialog.lstPaymentMethod.setListData(vData); if(RefStoreConfigurationUtil.isRefundTenderRestrictionEnabled()) { storePaymentMethods = vData; if(bdInvoiceTotal.compareTo(new BigDecimal("0.00")) < 0) { payPanel.pnlTenderTypes.setVisible(true); finalizeBaseDialog.btnMgrOverride.setVisible(true); finalizeBaseDialog.btnMgrOverride.setEnabled(true); paymentController.setReturnPaymentMethod(invoiceVO,customerVO,vData); Vector newRefundTenderListForUI = paymentController.getNewRefundPaymentListForUI(); if(newRefundTenderListForUI!= null && !(newRefundTenderListForUI.size() == 0)) { finalizeBaseDialog.lstPaymentMethod.setListData(newRefundTenderListForUI); } }else { payPanel.pnlTenderTypes.setVisible(false); payPanel.pnlRefundTenderMgrApproval.setVisible(false); finalizeBaseDialog.btnMgrOverride.setVisible(false); finalizeBaseDialog.btnMgrOverride.setEnabled(false); finalizeBaseDialog.btnPrint.setEnabled(true); } } setWaitCursor(false); } private void addEasyPayCardToVDataIfEnabled(Locale applicationLocale, Vector vData) { Vector creditCards = clientApplicationContext.getRefTableDAO().getTenderTypes( RefTenderTypeCategory.CREDIT_CARD, clientApplicationContext.getLocation(), applicationLocale.getLanguage()); boolean isChargeCustomer = (customerVO != null && customerVO.getBillTypeCode() != null) ? customerVO.getBillTypeCode().equalsIgnoreCase(RefBillingType.CHARGE_ONLY) : false; if (!creditCards.isEmpty()) { creditCards.forEach(item -> { RefTableVO refTableVO = (RefTableVO) item; if (RefTenderType.NAPA_EASYPAY_CARD == refTableVO.getID() && !isChargeCustomer) { vData.add( new IDValuePairVO(refTableVO.getID(), refTableVO.getDescription())); } }); } } /** * This method checks if the fleet card is accepted or not * @param fleetCardAccepted * @return boolean */ private boolean isFleetCardAccepted(byte fleetCardAccepted) { return (fleetCardAccepted == 1 || fleetCardAccepted == 11); } /** * This method loads tender type based on customer Napa Online * flag. Current Phone room controller implement it to pull * data from remote store. Rest all use base class method. * @param isNapaOnlineCustomer * @param applicationLocale * @return */ protected Vector getPaymentTypeList(boolean isNapaOnlineCustomer, Locale applicationLocale) { return clientApplicationContext.getRefTableDAO().getTenderTypeCatList( isNapaOnlineCustomer ? RefBillingType.CASH_ONLY : customerVO.getBillTypeCode(), clientApplicationContext.getLocation(), applicationLocale.getLanguage()); } /** * This method loads printer into cbPrinter. To make all four controllers to use * this method following methods are used so that all controllers work. * * getPrinterList : This method loads printer. Current Phone room controller * implement it to pull data from remote store. Rest all use * base class method. * * isNonEmpty : This method checks if the argument passed is empty. * Current Phone room controller has specific implementation. * Rest all return default value as 'true'. */ private void loadPrinters() { FwoPrinterSelectionSettings printerSelectionSettings = new FwoPrinterSelectionSettings(); printerSelectionSettings.setPrinterType("I"); printerSelectionSettings.setPrinterUse("Invoices"); printerSelectionSettings.setClientIPAddress(clientApplicationContext .getClientIPAddress()); Vector vPrinterList = getPrinterList(printerSelectionSettings); if (finalizeBaseDialog.cbPrinter.getItemCount() > 0) { finalizeBaseDialog.cbPrinter.removeAllItems(); } if (isNonEmpty(vPrinterList)) { finalizeBaseDialog.cbPrinter.setModel(new DefaultComboBoxModel(vPrinterList)); finalizeBaseDialog.cbPrinter.setSelectedIndex(0); } } /** * This method loads printer. Current Phone room controller implement * it to pull data from remote store. Rest all use base class method. * @param printerSelectionSettings * @return */ protected Vector getPrinterList(FwoPrinterSelectionSettings printerSelectionSettings) { return clientApplicationContext.getHardwareDAO().getPrinterList(printerSelectionSettings); } /** * This method checks if the argument passed is empty. Current Phone room * controller has specific implementation. Rest all return default value * as 'true'. * @param object Object to be verified. * @return true if passed argument is not empty. */ protected boolean isNonEmpty(Object object) { return true; } /** * This method loads MISC adjustment components. To make all four * controllers to use this method following method is used so * that all controllers work. */ protected void loadMiscAdjustment() { InvoicingProfileVO invoicingProfileVO = getInvoicingProfile(); if (invoicingProfileVO.getAllowMiscAdjustment().booleanValue()) { if ((customerVO.getMiscInvDiscountRefOptionCD() != null) && customerVO.getMiscInvDiscountRefOptionCD() .equalsIgnoreCase("N")) { finalizeBaseDialog.fldMiscAdjustments.setText("0"); } else { finalizeBaseDialog.fldMiscAdjustments.setText(customerVO .getMiscInvDiscPercent().toString()); } calculateMiscAdjustments(); } else { allowMiscAdj = false; finalizeBaseDialog.lblMiscAdjustments.setEnabled(false); finalizeBaseDialog.fldMiscAdjustments.setEnabled(false); finalizeBaseDialog.fldMiscAdjustments.setText("0"); finalizeBaseDialog.dlblMiscAdjustments.setText("0.00"); invoiceVO.setMiscAdjustmentsPercent(new Short("0")); invoiceVO.setMiscAdjustments(BD_ZERO); customerVO.setMiscInvDiscountRefOptionCD("N"); } } protected InvoicingProfileVO getInvoicingProfile() { return clientApplicationContext.getProfile( Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()).getInvoicingProfile(); } /** * This method loads delivery settings of a customer. To make all four controllers * to use this method following methods are used so that all controllers work. * loadAlwaysDeliveryDefaults : The implementation of this method performs * business for always delivery customer. The * base controller method is used by Regular, * Non phone room and phone room controller. * Optional checkout controller has its own * implementation. * loadOptionalNeverDeliveryDefaults : The implementation of this method performs * business for optional and never delivery * customer. All controller has their own * implementation. */ private void loadDeliveryDefaults() { int priorityID = -1; String charge = "0.00"; BigDecimal minAmtForFreeDelivery = null; if (customerDeliveryVO != null) { if (invoiceVO.getSubTotal().doubleValue() < (double) 0.00) { deliveryFlag = "O"; } else if (customerDeliveryVO.getDeliveryRefOptionCD() != null) { deliveryFlag = customerDeliveryVO.getDeliveryRefOptionCD(); } if (CustomerBL.isNapaOnlineCustomer(customerVO)) { deliveryFlag = "O"; setOptionalDelivery(false); } if (customerDeliveryVO.getDeliveryPriorityID() != null) { priorityID = customerDeliveryVO.getDeliveryPriorityID() .intValue(); logger.debug("---- loadDeliveryDefault, priorityID= " + priorityID); } if (customerDeliveryVO.getDeliveryCharge() != null) { charge = "" + customerDeliveryVO.getDeliveryCharge(); } if (customerDeliveryVO.getMinAmtFreeDelivery() != null) { minAmtForFreeDelivery = customerDeliveryVO .getMinAmtFreeDelivery(); } } loadAlwaysDeliveryDefaults(priorityID); loadOptionalNeverDeliveryDefaults(priorityID); // if invoice total > than the min_amount_free_delivery, disable // delivery amount field. if (minAmtForFreeDelivery == null || minAmtForFreeDelivery.doubleValue() == (double) 0.00 || invoiceVO.getSubTotal().compareTo(minAmtForFreeDelivery) < 0) { if (isDeliveryChecked()) { finalizeBaseDialog.lblDeliveryCharge.setEnabled(true); finalizeBaseDialog.fldDeliveryCharge.setEnabled(true); finalizeBaseDialog.fldDeliveryCharge.setText(charge); finalizeBaseDialog.dlblDeliveryCharge.setText(charge); } else { finalizeBaseDialog.fldDeliveryCharge.setText("0.00"); finalizeBaseDialog.dlblDeliveryCharge.setText("0.00"); } } else if (invoiceVO.getSubTotal().compareTo(minAmtForFreeDelivery) >= 0) { finalizeBaseDialog.fldDeliveryCharge.setText("0.00"); finalizeBaseDialog.dlblDeliveryCharge.setText("0.00"); } checkDeliveryCharge(); } /** * The implementation of this method performs business for always delivery * customer. The base controller method is used by Regular, Non phone room * and phone room controller. Optional checkout controller has its own * implementation. This method uses following method so that all three * controller can use this method. * * setDelivery : This method set the delivery component for each controller. * This is used since three types of UI component is used for * delivery among all controllers. * @param priorityID The delivery priority id. */ protected void loadAlwaysDeliveryDefaults(int priorityID) { BigDecimal bdInvSubtotal = invoiceVO.getSubTotal(); // delivery option is Always, do not disable the checkbox, enable the // fields // user can uncheck the check box if (bdInvSubtotal != null && bdInvSubtotal.doubleValue() >= (double) 0.00) { if ((deliveryFlag.equals("A") && invoiceVO .getSavedInvoiceIdForDeletion() == null) || (invoiceVO.getDeliveryFlag() != null && invoiceVO .getDeliveryFlag().booleanValue())) { setDelivery(true); checkDeliveryState(); enableDelivery(priorityID); } else if (deliveryFlag.equals("A") && invoiceVO.getSavedInvoiceIdForDeletion() != null && invoiceVO.getDeliveryFlag() != null && !invoiceVO.getDeliveryFlag().booleanValue()) { enableDelivery(priorityID); } } } /** * This method verifies the delivery info. * @return true if delivery info is successfully validated. */ private boolean isDeliveryInfoValid() { if (!isDeliveryChecked()) { return true; } if (finalizeBaseDialog.rbDeliveryTime.isSelected()) { if (finalizeBaseDialog.fldDeliveryDate.getText().trim().equals("")) { finalizeBaseDialog.lblErrorMsg .setText(strMustEnterDeliveryDate); finalizeBaseDialog.rbDeliveryTime .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryTime)); return false; } if (finalizeBaseDialog.fldDeliveryTime.getText().trim().equals("")) { finalizeBaseDialog.lblErrorMsg .setText(strMustEnterDeliveryTime); finalizeBaseDialog.fldDeliveryDate .dispatchEvent(pressTabKey(finalizeBaseDialog.fldDeliveryDate)); return false; } } if (finalizeBaseDialog.fldDeliveryMethod.getText().trim().equals("")) { finalizeBaseDialog.lblErrorMsg.setText(strMustEnterDeliveryMethod); if (finalizeBaseDialog.rbDeliveryPriority.isSelected()) { finalizeBaseDialog.cbDeliveryPriority .dispatchEvent(pressTabKey(finalizeBaseDialog.cbDeliveryPriority)); } else { finalizeBaseDialog.fldDeliveryTime .dispatchEvent(pressTabKey(finalizeBaseDialog.fldDeliveryTime)); } return false; } return true; } /** * This method reset screen components. To make all four controllers to use * this method following method is used so that all controllers work. * * clearAttention : This method clear the Attention field. Current phone * room controller has implementation of this method. Rest * has empty implementation. */ private void doCancel() { invoiceVO.setLoyaltyCustomerLookup(null); if(isBopisInvoice){ removeRewardLineItemIfExists(); } if (isNapaRewardProgram){ removeRewardLineItemIfExists(); if (isStartTransactionSuccessful && request!=null){ request.setTransactionIdentifier(populateTransactionIdentifierArray()); request.setCorrelationId(getCorrelationID()); if(isNapaRewardsProgramVersion2Active) { request.setLineItems(getLoyaltyEligibleLineItems(invoiceVO)); } loyaltyProgramService.cancelTransaction(request); } } resetValues(); resetApprovalInfo(invoiceVO); resetDelivery(); resetTaxDecision(); resetTaxInfo(); clearAttention(); finalizeBaseDialog.fldMiscAdjustments.setText("0"); invoiceVO.setMiscAdjustmentsPercent(new Short("0")); invoiceVO.setMiscAdjustments(BD_ZERO); invoiceVO.setRewardAmount(BD_ZERO); handleDisplayInvoiceSummary(null); finalizeBaseDialog.setVisible(false); } /** * This method is to reset the original tax decision. */ private void resetTaxDecision() { Vector originalItems = originalInvoiceVo.getLineItems(); Vector modifiedItems = invoiceVO.getLineItems(); for (int index = 0; index < modifiedItems.size(); index++) { if (modifiedItems.get(index) instanceof BaseLineItemVO) { BaseLineItemVO modifiedBaseLine = (BaseLineItemVO) modifiedItems .get(index); modifiedBaseLine.setTaxable1(((BaseLineItemVO) originalItems .get(index)).getTaxable1()); modifiedBaseLine.setTaxable2(((BaseLineItemVO) originalItems .get(index)).getTaxable2()); } } } /** * This method is to reset the secondary tax decision. */ private void resetSecondaryTaxDecision() { Vector originalItems = originalInvoiceVo.getLineItems(); Vector modifiedItems = invoiceVO.getLineItems(); for (int index = 0; index < modifiedItems.size(); index++) { if (modifiedItems.get(index) instanceof BaseLineItemVO) { BaseLineItemVO modifiedBaseLine = (BaseLineItemVO) modifiedItems .get(index); modifiedBaseLine.setTaxable2(((BaseLineItemVO) originalItems .get(index)).getTaxable2()); } } } /** * This method is to reset the original tax table vo's. */ private void resetTaxInfo() { invoiceVO .setPrimaryTaxTableVO(originalInvoiceVo.getPrimaryTaxTableVO()); invoiceVO .setPrimaryTaxTableID(originalInvoiceVo.getPrimaryTaxTableID()); invoiceVO.setTaxPercent1(originalInvoiceVo.getTaxPercent1()); invoiceVO.setSecondaryTaxTableVO(originalInvoiceVo .getSecondaryTaxTableVO()); invoiceVO.setSecondaryTaxTableID(originalInvoiceVo .getSecondaryTaxTableID()); invoiceVO.setTaxPercent2(originalInvoiceVo.getTaxPercent2()); } /** * This method is to set the primary tax decision as the secondary tax * decision for the line items. */ private void setPrimaryAsSecondary() { Vector invoiceLineItems = invoiceVO.getLineItems(); for (int index = 0; index < invoiceLineItems.size(); index++) { if (invoiceLineItems.get(index) instanceof BaseLineItemVO) { BaseLineItemVO baseLineItemVO = (BaseLineItemVO) invoiceLineItems .get(index); if (!(baseLineItemVO.getRefInvoiceLineItemTypeID().intValue() == RefInvoiceLineItemType.NAPA_REWARDS)) { baseLineItemVO.setTaxable2(baseLineItemVO.getTaxable1()); } } } } /** * This method is used to reset approval information. * * @param invoiceVO value object for the invoice */ public void resetApprovalInfo(InvoiceVO invoiceVO) { Vector baseLineItems = invoiceVO.getLineItems(); if (baseLineItems != null && baseLineItems.size() > 0) { for (int i = 0; i < baseLineItems.size(); i++) { InvoiceLineItemVO iliVO = (InvoiceLineItemVO) baseLineItems .get(i); if (iliVO instanceof BaseLineItemVO) { Vector returnItems = ((BaseLineItemVO) iliVO) .getReturnItems(); if (returnItems != null && returnItems.size() > 0) { for (int j = 0; j < returnItems.size(); j++) { InvoiceLineItemReturnVO ilirVO = (InvoiceLineItemReturnVO) returnItems .get(j); ilirVO.setApprovedByEmployeeID(null); } } } } } } /* this method helps keep 1sec quite time between 2 print invoice button events to midigate duplicated invoice issues */ private boolean isWithinPrintButtonQuietTime() { long currentTimestamp = System.currentTimeMillis(); if ((currentTimestamp - this.lastPrintInvoiceTime) < 1000L) { // ignore potential double clicks that cause duplicated invoices logger.warn("ignore Print Button event within 1 sec after the last one"); return true; } this.lastPrintInvoiceTime = currentTimestamp; return false; } /* * (non-Javadoc) * * @see * java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) * To make all four controllers to use this method following methods are used * so that all controllers work. * * isOptionalDelivery : This method check whether optional delivery * flag is enabled. Current Optional * controller implement this method. Rest all * use base controller method which return * 'false'. * processSpecificRemoveCommand : This method performs certain logic before * calling remove method. Current regular * controller implement this. Rest all use * base class implementation. * postProcessPrintCommand : This method performs things after processing * print command. Current phone room controller * implement this. Rest all use empty * implementation. * postProcessSaveCommand : This method performs things after processing * save command. Current phone room controller * implement this. Rest all use empty * implementation. */ public void actionPerformed(ActionEvent ae) { if (actionInProgress) { // Posting and priting is in progress, ignore // the other request to process. logger.debug("The new request to print is ignored"); return; } if (ae.getSource() instanceof JButton) { if (ae.getActionCommand().equals(FinalizeBaseDialog.CANCEL_COMMAND)) { if (!canPerformCancelEraseButtonAction()) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "2279"); actionInProgress = false; return; } // Check if any Gift Cards are activated or loaded on the invoice (TNSS-5060). if (GiftCardBL.doesInvoiceContainsActivatedOrReloadedGC(invoiceVO)) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "10736"); actionInProgress = false; return; } // Check if any Gift Cards are eligible for Cash Payout on the invoice if (GiftCardBL.doesInvoiceContainBarcodedNAPAGiftCardReturnItem(invoiceVO)) { clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "10742"); actionInProgress = false; return; } // this invokelater is from bug 20462 SwingUtilities.invokeLater(new Runnable() { public void run() { doCancel(); } }); } else if (ae.getActionCommand().equals(FinalizeBaseDialog.PRINT_COMMAND)) { if (Boolean.TRUE.equals(RefStoreConfigurationUtil.isRefundTenderRestrictionEnabled())) { finalizeBaseDialog.btnMgrOverride.setEnabled(false); payPanel.pnlRefundTenderMgrApproval.setVisible(false); payPanel.pnlTenderTypes.setVisible(false); } if (this.isWithinPrintButtonQuietTime()) { return; } // Notify user if Invoice Total exceeds invoicing profile Min/Max amount. BigDecimal invoiceTotalWithAlternateCore = BD_ZERO; InvoicingProfileVO invoicingProfile = null; if(null!=invoiceVO && invoiceVO.isPhoneRoomMessagesFlag()) { invoicingProfile = getRemoteInvoicingProfileVO(); } else { invoicingProfile = clientApplicationContext.getProfile( Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()) .getInvoicingProfile(); } invoiceTotalWithAlternateCore = (invoiceVO.getInvoiceTotal() != null && invoiceVO.getAlternateCoreSubTotal() != null && (invoiceVO .getAlternateCoreSubTotal().abs()).signum() > 0) ? invoiceVO .getInvoiceTotal().add(invoiceVO.getAlternateCoreSubTotal()) : invoiceVO .getInvoiceTotal(); if (!CommonInvoiceBL.authorizeInvoiceAmount(finalizeBaseDialog, invoicingProfile, invoiceTotalWithAlternateCore)) { actionInProgress = false; return; } if(StringUtils.isNotEmpty(customerVO.getEinvoiceEmailAddress())) { invoiceVO.setEinvoiceEmailAddress(customerVO.getEinvoiceEmailAddress()); } final Integer refElectronicInvoiceVendorId; if(null!=invoiceVO && invoiceVO.isPhoneRoomMessagesFlag()) { refElectronicInvoiceVendorId = getRemoteInvoicingProfileVO().getRefElectronicInvoiceVendorId(); } else { refElectronicInvoiceVendorId = clientApplicationContext .getProfile(Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()).getInvoicingProfile() .getRefElectronicInvoiceVendorId(); } if (refElectronicInvoiceVendorId != null && refElectronicInvoiceVendorId.intValue() == 1) { SwingUtilities.invokeLater(new Runnable() { public void run() { if ( askForCustomerRFC() && clientApplicationContext.getMessageMgr().showMessageYesNo( finalizeBaseDialog, "10107")) { displayCustomerInfoModal(false, invoiceVO); } else { InvoicingProfileVO invoicingProfileVO = null; if(null!=invoiceVO && invoiceVO.isPhoneRoomMessagesFlag()) { invoicingProfileVO = getRemoteInvoicingProfileVO(); invoiceVO.setSavedInvoiceType(TsoConstant.CALL_CENTER_SAVED_INVOICE); } else { invoicingProfileVO = getInvoicingProfile(); invoiceVO.setSavedInvoiceType(TsoConstant.NORMAL_SAVED_INVOICE); } isOk = false; if ("Y".equalsIgnoreCase(invoicingProfileVO.getUseCepdiV2()) && isDeliveryChecked() && !askForCustomerRFC()) { transportVO = new TransportInvoiceInfoVO(); displayTransportInfoModal(transportVO); isOk = transportInfoController.isOk(); if (isOk == false) { return; } else { invoiceVO.setTransportInvInfoVO(transportVO); } } if(CustomerBL.isWalkInCustomer(customerVO)){ StoreProfileVO storeProfile = ApplicationContext.getInstance() .getProfile(Profile.POINT_OF_SALE_CLIENT, loc.intValue()) .getStoreProfile(); invoiceVO.setRfcNumber(storeProfile.getFederalTaxID()); }else{ invoiceVO.setCustomerEmail(customerVO.getEmailAddress()); invoiceVO.setCustomerPhone(customerVO.getPhone()); invoiceVO.setRfcNumber(customerVO.getTaxExemptNumberPrimary()); } } invoiceVO.setRefElectronicInvoiceTypeCd(customerVO .getDefaultRefElectronicInvoiceTypeCd()); SwingUtilities.invokeLater(new Runnable() { public void run() { if (!isOptionalDelivery()) { logger.debug("Now processing the print-command request.."); actionInProgress = true; // in rare circumstances, invoice payments are missing (the // invoiceListModel below is empty). // // we're not 100% sure where this is happening, but this // will help us track down the issue if // it happens again. // // note - if we get the error at this point in the code, it // means that the print button is // being enabled (or is somehow clickable) even when there // are no // if (!validateInvoicePayments(invoiceListModel)) { logger.warn("Invoice Payments are empty. This suggests that the print button is clickable" + " or engageable at a point when no payments have been added to the invoice."); if (!finalizeBaseDialog.btnPrint.isEnabled()) { logger.warn("Print button is enabled when it shouldn't be"); } } processPrintCommand(); // If saved invoice exists in phone room store, delete it. postProcessPrintCommand(); } else { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } }); } }); } else { if (!isOptionalDelivery()) { logger.debug("Now processing the print-command request.."); actionInProgress = true; // in rare circumstances, invoice payments are missing (the // invoiceListModel below is empty). // // we're not 100% sure where this is happening, but this // will help us track down the issue if // it happens again. // // note - if we get the error at this point in the code, it // means that the print button is // being enabled (or is somehow clickable) even when there // are no // if (!validateInvoicePayments(invoiceListModel)) { logger.warn("Invoice Payments are empty. This suggests that the print button is clickable" + " or engageable at a point when no payments have been added to the invoice."); if (!finalizeBaseDialog.btnPrint.isEnabled()) { logger.warn("Print button is enabled when it shouldn't be"); } } processPrintCommand(); // If saved invoice exists in phone room store, delete it. postProcessPrintCommand(); } else { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } if(bopisPaymentFailed) { changeTypeIfBopisPaymentFailed(); bopisPaymentFailed = false; } } else if (ae.getActionCommand().equals( FinalizeBaseDialog.VOID_COMMAND)) { if (!isOptionalDelivery()) { actionInProgress = true; if (InvoiceBL.hasNXPItems(invoiceVO)) { boolean voidInvoice = clientApplicationContext.getMessageMgr() .showMessageNoYes(finalizeBaseDialog, "9970"); if (!voidInvoice) { return; } } voidInvoice(); } else { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } else if (ae.getActionCommand().equals( FinalizeBaseDialog.SAVE_COMMAND)) { if(isBopisInvoice){ removeRewardLineItemIfExists(); } if (invoiceVO.getSavedInvoiceIdForDeletion() != null && InvoiceBL.hasNxpDirectShipApprovedItem(invoiceVO) && customerVO.getDirectShipEligible().booleanValue()) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "10085"); actionInProgress = false; return; } if (!isOptionalDelivery()) { actionInProgress = true; processSaveCommand(true); // If saved invoice exists in phone room store, delete it. postProcessSaveCommand(); } else { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } else if (ae.getActionCommand().equals( FinalizeBaseDialog.SUBMIT_COMMAND)) { if (invoiceVO.getSavedInvoiceIdForDeletion() != null && InvoiceBL.hasNxpDirectShipApprovedItem(invoiceVO) && customerVO.getDirectShipEligible().booleanValue()) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "10085"); actionInProgress = false; return; } actionInProgress = true; processSaveCommand(false); // If saved invoice exists in phone room store, delete it. postProcessSaveCommand(); } else if (ae.getActionCommand().equals( FinalizeBaseDialog.ERASE_COMMAND)) { if (InvoiceBL.hasNxpDirectShipApprovedItem(invoiceVO) && customerVO.getDirectShipEligible().booleanValue()) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "10085"); actionInProgress = false; return; } if (!isOptionalDelivery()) { if (!canPerformCancelEraseButtonAction()) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "2277"); actionInProgress = false; return; } // Check if any Gift Cards are activated or loaded on the invoice (TNSS-5060). if (GiftCardBL.doesInvoiceContainsActivatedOrReloadedGC(invoiceVO)) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "10736"); actionInProgress = false; return; } // Check if any Gift Cards are eligible for Cash Payout on the invoice if (GiftCardBL.doesInvoiceContainBarcodedNAPAGiftCardReturnItem(invoiceVO)) { clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "10742"); actionInProgress = false; return; } /* * Added for RADS: Retrieve the discrepancy list from * Invoice VO this list contain the discrepancy added when * user deletes a line item */ List radsDiscrepancyLogsFromInvoice = invoiceVO .getRadsDiscrepancyLogList(); boolean eraseInvoiceInfo = clientApplicationContext .getMessageMgr().showMessageNoYes( finalizeBaseDialog, "1235"); // If we choose reload, reload if (eraseInvoiceInfo) { actionInProgress = true; // For NXP Interstore Invoice boolean isNxpInterstoreInvoice = InvoiceBL.doesInvoiceContainNXPInterStoreOrder(invoiceVO); if (isNxpInterstoreInvoice) { try{ boolean isCancelInvoice = true; sendNXPInterstoreUpdateSalesOrderRequest(invoiceVO, isCancelInvoice); } catch(Throwable e) { logger.error("Error in sending interstore update sales order.."); } } if (invoiceVO.getSavedInvoiceIdForDeletion() != null) { try { clientApplicationContext.getInvoiceDAO() .deleteSavedInvoice(invoiceVO, Boolean.FALSE); } catch (ApplicationException e) { logger.error(ae.toString(), e); // delete error clientApplicationContext .getMessageMgr() .showMessage(finalizeBaseDialog, "2228"); return; } } InvoiceBL.closePpseSession(invoiceVO); if(isBopisInvoice){ removeRewardLineItemIfExists(); } if (isNapaRewardProgram){ removeRewardLineItemIfExists(); if (isStartTransactionSuccessful && request!=null){ request.setTransactionIdentifier(populateTransactionIdentifierArray()); request.setCorrelationId(getCorrelationID()); if (isNapaRewardsProgramVersion2Active) { request.setLineItems(getLoyaltyEligibleLineItems(invoiceVO)); } loyaltyProgramService.cancelTransaction(request); loyaltyCustomerLookup = null; } } // no bug listed this invoke later was put in on // 12/30/02 SwingUtilities.invokeLater(new Runnable() { public void run() { clientApplicationContext .getPointOfSaleEventDispatcher() .fireInvoiceCancelled( new InvoiceEvent(this, new InvoiceVO())); finalizeBaseDialog.setVisible(false); if (clientApplicationContext.getPOSState() .getState() == POSStateVO.CASHIER) pointOfSaleEventDispatcher .fireChangedToCashier(null); } }); createRadsDiscrepancyLog(invoiceVO, radsDiscrepancyLogsFromInvoice); invoiceVO = null; } } else { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } else if (ae.getActionCommand().equals( FinalizeBaseDialog.REMOVE_COMMAND)) { if (processSpecificRemoveCommand()) { removePayment(); } } else if (ae.getActionCommand().equals( FinalizeBaseDialog.EXPRESSCHECKOUT_COMMAND)) { if (!isOptionalDelivery()) { if (!canPerformSaveExpressCheckoutButtonAction()) { clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "2278"); actionInProgress = false; return; } else if (GiftCardBL.doesInvoiceContainsActivatedOrReloadedGC(invoiceVO)) { // Check if any Gift Cards are activated or loaded on the invoice // (TNSS-5060). clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "10736"); actionInProgress = false; return; } else if (GiftCardBL.doesInvoiceContainBarcodedNAPAGiftCardReturnItem(invoiceVO)) { // Check if any Gift Cards are eligible for Cash Payout on the invoice clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "10742"); actionInProgress = false; return; } actionInProgress = true; doExpressCheckout(); } else { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } else if (ae.getActionCommand().equals( FinalizeBaseDialog.MGR_OVERRIDE_COMMAND)) { if (RefStoreConfigurationUtil.isRefundTenderRestrictionEnabled()) { //PaymentPanel payPanl2 = (PaymentPanel) paymentController.getView(); if(payPanel != null) { payPanel.btnCancel.doClick(); } Container parentView = payPanel; while (!(parentView instanceof Frame) && (parentView != null)) { parentView = parentView.getParent(); } RefundRestrictMgrOverrideController refundRestrictMgrOverrideController= new RefundRestrictMgrOverrideController((Frame)parentView,paymentController, bdInvoiceTotal,storePaymentMethods); refundRestrictMgrOverrideController.setViewVisible(true); } } } else if (ae.getSource() instanceof JRadioButton) { if (((JRadioButton) ae.getSource()).getName().equals( "rbDeliveryPriority")) { setDeliveryOption(true); finalizeBaseDialog.rbDeliveryPriority .dispatchEvent(pressTabKey(finalizeBaseDialog)); } else if (((JRadioButton) ae.getSource()).getName().equals( "rbDeliveryTime")) { setDeliveryOption(false); finalizeBaseDialog.rbDeliveryTime .dispatchEvent(pressTabKey(finalizeBaseDialog)); } else if (((JRadioButton) ae.getSource()).getName().equals("rbAM")) { // set to AM now if it is set to PM String tTime = finalizeBaseDialog.fldDeliveryTime.getText() .trim(); if (tTime != "" && tTime.toUpperCase().endsWith("PM")) { int idx = finalizeBaseDialog.fldDeliveryTime.getText() .toUpperCase().indexOf("PM"); String tTmpTime = tTime.substring(0, idx).trim(); finalizeBaseDialog.fldDeliveryTime .setText(tTmpTime + " AM"); } } else if (((JRadioButton) ae.getSource()).getName().equals("rbPM")) { // set to PM now if it is set to AM String tTime = finalizeBaseDialog.fldDeliveryTime.getText() .trim(); if (tTime != "" && tTime.toUpperCase().endsWith("AM")) { int idx = finalizeBaseDialog.fldDeliveryTime.getText() .toUpperCase().indexOf("AM"); String tTmpTime = tTime.substring(0, idx).trim(); finalizeBaseDialog.fldDeliveryTime .setText(tTmpTime + " PM"); } } else if (((JRadioButton) ae.getSource()).getName().equals( "rbDeliveryYes")) { if (!finalizeBaseDialog.rbDeliveryYes.isSelected()) { finalizeBaseDialog.rbDeliveryYes.setSelected(true); } setOptionalDelivery(false); finalizeBaseDialog.rbDeliveryNo.setSelected(false); handleCDFLine(true); checkDeliveryState(); loadDeliveryDefaults(); verifyForCustomerDeliveryTax(); calculateInvoiceTotal(); finalizeBaseDialog.rbDeliveryYes .dispatchEvent(pressTabKey(finalizeBaseDialog)); } else if (((JRadioButton) ae.getSource()).getName().equals( "rbDeliveryNo")) { if (!finalizeBaseDialog.rbDeliveryNo.isSelected()) { finalizeBaseDialog.rbDeliveryNo.setSelected(true); } setOptionalDelivery(false); finalizeBaseDialog.rbDeliveryYes.setSelected(false); handleCDFLine(false); checkDeliveryState(); resetDelivery(); resetPrimaryTax(); calculateInvoiceTotal(); finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog)); } } else if (ae.getSource() instanceof JCheckBox) { checkDeliveryState(); if (finalizeBaseDialog.chkDelivery.isSelected()) { handleCDFLine(true); loadDeliveryDefaults(); verifyForCustomerDeliveryTax(); } else { handleCDFLine(false); resetDelivery(); resetPrimaryTax(); } calculateInvoiceTotal(); finalizeBaseDialog.chkDelivery .dispatchEvent(pressTabKey(finalizeBaseDialog)); } else if (ae.getSource() instanceof JComboBox) { if (((JComboBox) ae.getSource()).getName().equals("cbDelivery")) { if (customerVO != null) { checkDeliveryState(); if (finalizeBaseDialog.cbDelivery.getSelectedItem().equals( DELIVERY_YES)) { finalizeBaseDialog.cbDelivery.removeItem(DELIVERY_EMPTY); finalizeBaseDialog.lblErrorMsg.setText(returnEmptyStringIfMatched( finalizeBaseDialog.lblErrorMsg.getText(), strDeliveryRequired)); handleCDFLine(true); loadDeliveryDefaults(); verifyForCustomerDeliveryTax(); } else if (finalizeBaseDialog.cbDelivery.getSelectedItem() .equals(DELIVERY_NO)) { finalizeBaseDialog.cbDelivery.removeItem(DELIVERY_EMPTY); finalizeBaseDialog.lblErrorMsg.setText(returnEmptyStringIfMatched( finalizeBaseDialog.lblErrorMsg.getText(), strDeliveryRequired)); if (invoiceVO != null) { handleCDFLine(false); resetDelivery(); resetPrimaryTax(); } } calculateInvoiceTotal(); } } else if (ae.getSource().equals(finalizeBaseDialog.cbTax1)) { if (!isOptionalDelivery()) { if (invoiceVO.getManualTransaction().booleanValue()) { processManualCbTax1(); } else { processCbTax1(); } } else { if (finalizeBaseDialog.cbTax1.getItemCount() > 0) { finalizeBaseDialog.cbTax1 .setSelectedIndex(defaultCustomerTaxId); } } } else if (ae.getSource().equals(finalizeBaseDialog.cbPrinter)) { if (isOptionalDelivery()) { if (finalizeBaseDialog.cbPrinter.getItemCount() > 0) { finalizeBaseDialog.cbPrinter .setSelectedIndex(getPrinterIndex(defaultPrinterID)); } } } } } /** * This method is to create Transaction Identifier Array. */ private TransactionIdentifier[] populateTransactionIdentifierArray() { if (isNotEmpty(loyaltyInvoiceExternalIdentifier)){ TransactionIdentifier[] transactionIdentifierArray = new TransactionIdentifier[1]; TransactionIdentifier transactionIdentifier = new TransactionIdentifier(); transactionIdentifier.setType(LoyaltyConstants.CURRENT_VENDOR); transactionIdentifier.setInvoiceNumber(loyaltyInvoiceExternalIdentifier); transactionIdentifierArray[0] = transactionIdentifier; return transactionIdentifierArray; } return null; } /** * This method performs action on click of Print button. To make all four controllers * to use this method following methods are used so that all controllers work. * * isPODeliveryValidated : This method validates PO. Current Regular and Optional * Controller has common implementation. Phone room and * and Non Phone room has common implementation. * * processIPCCanceled : This method process cancellation of IPC. Current * Regular and Optional Controller has common * implementation. Phone room and and Non Phone room * return 'false'. * processPaymentCards : This method process payment cards. Current Regular * Controller has its implementation. Rest all use base * class method. * paymentAndInvoiceListModelConsistencyCheck: * This method logs if payment is empty. This is implemented * by Regular and Optional Checkout controller. Both Phone * room and Non Phone Room has empty implementation. */ private void processPrintCommand() { SalesOrderVO salesOrderVO = getSalesOrderVO(); boolean okayToPrint = true; // check system maintenance flag, if maintenance in progress, display // message // and don't continue printing. final Boolean maintInProgress = clientApplicationContext.getSystemDAO() .maintenanceInProgress(loc); if (maintInProgress.booleanValue() && !invoiceVO.getManualTransaction().booleanValue()) { ClientApplicationContext.getClientApplicationContext() .getMessageMgr().showMessage(finalizeBaseDialog, "1373"); okayToPrint = false; } if (okayToPrint) { if (!isDeliveryInfoValid()) { actionInProgress = false; return; } // we make a copy of the invoice payments because we believe that // the UI framework may, under certain very rare circumstances, // reset invoiceListModel to an empty list while the app is still // using it. To avoid this, we'll make a copy of the vector of // payments, and use that copy during the "threadable" portion of // the lifecycle. logger.debug("Making a copy of the invoice payments"); final Vector payments = copyInvoicePayments(invoiceListModel); if (!isPODeliveryValidated(true)) { actionInProgress = false; return; } if ( isChargeOnAccount() && isIthacaPrinterSelected() && !new Integer(1).equals(salesOrderVO.getRefOrderSubTypeId())) { okayToPrint = false; // this invoke later is just for a message. leave it SwingUtilities.invokeLater(new Runnable() { public void run() { ClientApplicationContext.getClientApplicationContext() .getMessageMgr() .showMessage(finalizeBaseDialog, "2203"); } }); finalizeBaseDialog.cbPONumber .dispatchEvent(pressTabKey(finalizeBaseDialog.cbPONumber)); actionInProgress = false; return; } // activate or reload barcode based NAPA Gift Card if (useNapaGCV2() && doesBarcodeBasedNapaGiftCardLineItemExists(invoiceVO.getLineItems()) && !activateOrReloadBarcodeBasedNapaGiftCards(invoiceVO.getLineItems())) { actionInProgress = false; return; } // Deduct amount from Gift cards which are eligible for Cash Payout if (InvoiceBL.useNapaGCv2() && !processBarcodedNapaGiftCardCashPayoutTransaction( invoiceVO.getLineItems(), finalizeBaseDialog, customerVO)) { actionInProgress = false; return; } // Handle NAPA Gift Card transactions. if (isNapaGiftCardLineItemExists(invoiceVO.getLineItems())) { if (!processPaymentCards()) { ClientApplicationContext.getClientApplicationContext() .getMessageMgr() .showMessage(finalizeBaseDialog, "5053"); actionInProgress = false; return; } } // Barcode based GiftCard Activations and Reload complete, modify note with last 4 digits of card num and append balance. if(useNapaGCV2()) { updateNoteWithCardNumAndBalance(invoiceVO.getLineItems()); } final MSHelper msHelper = MSHelper.getInstance(); final boolean isArBranch = msHelper.isArBranchType( Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()); final boolean isMsStore = msHelper.isMSStore( Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()); final boolean isOnServerFarm = msHelper.isOnServerFarm( Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()); paymentAndInvoiceListModelConsistencyCheck(payments); InvoicingProfileVO invoicingProfileVO = null; if(null!=invoiceVO && invoiceVO.isPhoneRoomMessagesFlag()) { invoicingProfileVO = getRemoteInvoicingProfileVO(); } else { invoicingProfileVO = getInvoicingProfile(); } if (isChargeOnAccount() && isIpcEnabled() && !CustomerBL.isTransferCustomer(customerVO) && ((!isDeliveryChecked() && invoiceVO.getInvoiceTotal().signum() >= 0 && invoicingProfileVO.getAllowChangeSigCaptureForChargeSale().booleanValue()) || (invoiceVO.getInvoiceTotal().signum() < 0 && invoicingProfileVO .getAllowChangeSigCaptureForChargeReturns().booleanValue()))) { // launch the dialogs PaymentCardDlg swipeCardPage = new PaymentCardDlg(finalizeBaseDialog, Profile.POINT_OF_SALE_CLIENT, invoiceVO.getInvoiceTotal()); swipeCardPage.setVisible(true); if (swipeCardPage.transactionSuccessful()) { InvoicePaymentVO vo = (InvoicePaymentVO) payments.elementAt(0); vo.setSignatureFile(swipeCardPage.getSignatureOnFile()); vo.setSignatureFileName(swipeCardPage.getSignatureFileName()); vo.setIpcJournalKey(swipeCardPage.getJournalKey()); payments.set(0, vo); } } if (isChargeOnAccount() && !invoiceVO.getManualTransaction().booleanValue() && (!isArBranch || (isMsStore && !isOnServerFarm))) { // some double focus issue no bug number 7/17/03 final boolean checkCredit = checkCredit(); SwingUtilities.invokeLater(new Runnable() { public void run() { sendPaymentInfo(checkCredit, payments); } }); } else { sendPaymentInfo(true, payments); } } else { actionInProgress = false; } } /** * Added for capturing invoice details while recalling saved invoice for factory orders TNSS-6633 * * @param * @return */ private void logInvoiceDetails() { if (invoiceVO.getPONumber() != null && invoiceVO.getLineItems() != null && invoiceVO.getSavedInvoiceIdForDeletion() != null) { logger.error("FinalizeInvoiceBaseController:logInvoiceDetails: for custID:" + invoiceVO.getCustomerID() + " /Number of line items:" + invoiceVO.getLineItems().size() + " /PONum:" + invoiceVO.getPONumber() + " /SessionId= " + invoiceVO.getSessionID() + " /SavedInvoiceID= " + invoiceVO.getSavedInvoiceIdForDeletion()); try { int lineCount = clientApplicationContext.getInvoiceDAO() .getSavedInvItemCount(invoiceVO.getSavedInvoiceIdForDeletion().intValue()); logger.error("InvoiceLineEntryController:lineCount from Saved invoice for custId:" + invoiceVO.getCustomerID() + " LineCount =" + lineCount); if (invoiceVO.getLineItems().size() != lineCount) { logger.error( "FinalizeInvoiceBaseController:Mismatch occured in saved invoice lineCount and invoiced lines for custId:" + invoiceVO.getCustomerID() + " /PONum:" + invoiceVO.getPONumber() + " SavedInvoiceLineCount = " + lineCount + " invoiceLineItemCount=" + invoiceVO.getLineItems().size() + " /SessionId= " + invoiceVO.getSessionID() + " /SavedInvoiceID= " + invoiceVO.getSavedInvoiceIdForDeletion()); } } catch (RemoteException e) { logger.error("RemoteException occurred while getting the count for Saved Invoice items.."+e); e.printStackTrace(); } catch (ApplicationException e) { logger.error("ApplicationException occurred while getting the count for Saved Invoice items.."+e); e.printStackTrace(); } } } /** * This method process payment cards. Current Optional Controller has * its implementation. Rest all use base class method. * @return */ protected boolean processPaymentCards() { boolean giftCardSuccess = true; if (isIpcEnabled()) { logger.debug("==========>>> ipc is on and trnx contains napa gift card "); giftCardSuccess = handleIPCNapaGiftCards(); } else { handleNapaGiftCardTransaction(); } return giftCardSuccess; } /** * This method handle IPC Napa Gift cards. * @return */ private boolean handleIPCNapaGiftCards() { if (invoiceVO == null) { return true; } final Vector invoiceLineItems = invoiceVO.getLineItems(); if (invoiceLineItems == null) { return true; } final List napaGiftCardItems = new ArrayList(); final int invoiceLineItemsSize = invoiceLineItems.size(); boolean gftRtn = false; for (int i = 0; i < invoiceLineItemsSize; i++) { final InvoiceLineItemVO invoiceLineItem = (InvoiceLineItemVO) invoiceLineItems .elementAt(i); if (invoiceLineItem instanceof BaseLineItemVO) { logger.debug("==========>>> getRefInvoiceLineItemTypeID = " + invoiceLineItem.getRefInvoiceLineItemTypeID() .intValue()); } if (invoiceLineItem instanceof BaseLineItemVO && (invoiceLineItem.getRefInvoiceLineItemTypeID().intValue() == RefInvoiceLineItemType.NAPA_GIFT_CARD || invoiceLineItem.getRefInvoiceLineItemTypeID().intValue() == RefInvoiceLineItemType.NEW_NAPA_GIFT_CARD)) { // Add to the NAPA Gift Card Items only if the line item is Gift // Card. napaGiftCardItems.add(invoiceLineItem); gftRtn = invoiceLineItem.getQuantityBilled().floatValue() < 0 ? true : false; } } logger.debug("==========>>> gftRtn = " + gftRtn); // If NAPA Gift card items is not empty then show gift card dialog. if (napaGiftCardItems.isEmpty()) { logger.debug("==========>>> napaGiftCardItems is empty! "); return true; } // mmtodo here what to do if invoice has both purchase and return of the // GFT line item? logger.debug("==========>>> handle IPCActivateGiftCardDialog next! "); final IPCActivateGiftCardDialog dlg = new IPCActivateGiftCardDialog( finalizeBaseDialog, napaGiftCardItems, customerVO.getBillTypeCode()); dlg.setVisible(true); return dlg.isAllActivated(); } /** * This method deletes all the payments from the Payments Tendered list one * at a time */ private void removePaymentTendered() { int size = invoiceListModel.getSize(); for (int index = size; index > 0; index--) { finalizeBaseDialog.lstPaymentsTendered.setSelectedIndex(index - 1); finalizeBaseDialog.sqfPaymentsTendered.setText(String.valueOf(index)); removePayment(); } finalizeBaseDialog.cbTax1.dispatchEvent(pressTabKey(finalizeBaseDialog.cbTax1)); } /** * This method launch Gift card controller if invoice contain Napa Gift card. */ protected void handleNapaGiftCardTransaction() { if (invoiceVO == null) { return; } final Vector invoiceLineItems = invoiceVO.getLineItems(); if (invoiceLineItems == null) { return; } final List napaGiftCardItems = new ArrayList(); final int invoiceLineItemsSize = invoiceLineItems.size(); for (int i = 0; i < invoiceLineItemsSize; i++) { final InvoiceLineItemVO invoiceLineItem = (InvoiceLineItemVO) invoiceLineItems .elementAt(i); if (invoiceLineItem instanceof BaseLineItemVO && invoiceLineItem.getRefInvoiceLineItemTypeID().intValue() == RefInvoiceLineItemType.NAPA_GIFT_CARD) { // Add to the NAPA Gift Card Items only if the line item is Gift // Card. napaGiftCardItems.add(new Integer(i)); } } // If NAPA Gift card items is not empty then show gift card dialog. if (!napaGiftCardItems.isEmpty()) { giftCardController.setInitialData(invoiceLineItems, napaGiftCardItems); setComponentFocus(((GiftCardDialog)giftCardController.getView()).cardNumberField); giftCardController.setViewVisible(true); } } /** * This method checks whether NAPA gift card line item exists or not. */ private boolean isNapaGiftCardLineItemExists(final Vector invoiceLineItems) { if (invoiceLineItems == null) { return false; } boolean giftCardExists = false; final int invoiceLineItemsSize = invoiceLineItems.size(); for (int i = 0; i < invoiceLineItemsSize; i++) { final InvoiceLineItemVO invoiceLineItem = (InvoiceLineItemVO) invoiceLineItems .elementAt(i); if (invoiceLineItem instanceof BaseLineItemVO) { if (invoiceLineItem.getRefInvoiceLineItemTypeID().intValue() == RefInvoiceLineItemType.NAPA_GIFT_CARD && !((BaseLineItemVO)invoiceLineItem).isNewGiftCard()) { giftCardExists = true; break; } } } return giftCardExists; } /** * This method validates whether user can perform Cancel/Erase. To make all four * controllers to use this method following method is used so that all * controllers work. * * isAllowInvoiceErase : This method checks for allowInvoiceErase flag of * invoicing profile. Phone room controller pulls this * value from remote store. Rest all use base * controller method. * @return */ protected boolean canPerformCancelEraseButtonAction() { if (customerVO.getBillTypeCode().equalsIgnoreCase( RefBillingType.CHARGE_ONLY)) { return true; } if (finalizeBaseDialog.sqfPaymentsTendered != null && finalizeBaseDialog.sqfPaymentsTendered .getCorrespondingList() != null && finalizeBaseDialog.sqfPaymentsTendered .getCorrespondingList().getModel() != null && finalizeBaseDialog.sqfPaymentsTendered .getCorrespondingList().getModel().getSize() > 0) { int iRows = finalizeBaseDialog.lstPaymentsTendered.getModel() .getSize(); InvoicePaymentVO invoicePaymentVO = null; for (int i = 0; (i < iRows); i++) { invoicePaymentVO = (InvoicePaymentVO) finalizeBaseDialog.lstPaymentsTendered .getModel().getElementAt(i); if (invoicePaymentVO.getTenderTypeID().intValue() == RefTenderType.CHARGE_ON_ACCOUNT || invoicePaymentVO.getTenderTypeID().intValue() == RefTenderType.NAPA_ONLINE ) { return true; } } return false; } if (isAllowInvoiceErase()) { return true; } return false; } /** * This method checks for allowInvoiceErase flag of invoicing profile. * Phone room controller pulls this value from remote store. Rest all * use base controller method. * * @return flag value. */ protected boolean isAllowInvoiceErase() { return clientApplicationContext .getProfile(Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()) .getInvoicingProfile().getAllowInvoiceErase().booleanValue(); } /** * This method performs action on Save & Submit button. All controller implement * this method to perform some logic apart from calling this base class method. * To make all four controllers to use this method following methods are used so * that all controllers work. * * isPackingCompleted : This is aswa related method. Current regular and optional * controller has common implementation of it. Rest * controller return false. * processPO : This method is used to process PO. Current regular and * optional controller has common implementation of it. Rest * controller return true. * processAttention : This method is used to process Attention. Current Phone * room and None phone room controller has common * implementation of it. Rest controller return false. * @param save */ protected void processSaveCommand(boolean save) { logger.debug("processSaveCommand()"); // Added for ASWA project - START if (isPackingCompleted()) { ClientApplicationContext.getClientApplicationContext() .getMessageMgr().showMessage(finalizeBaseDialog, "9602"); actionInProgress = false; return; } // Added for ASWA project - END if ((finalizeBaseDialog.sqfPaymentsTendered != null && finalizeBaseDialog.sqfPaymentsTendered .getCorrespondingList() != null && finalizeBaseDialog.sqfPaymentsTendered .getCorrespondingList().getModel() != null && finalizeBaseDialog.sqfPaymentsTendered .getCorrespondingList().getModel().getSize() > 0) && !canPerformSaveExpressCheckoutButtonAction()) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "2269"); actionInProgress = false; return; } // Check if any Gift Cards are activated or loaded on the invoice (TNSS-5060). if (GiftCardBL.doesInvoiceContainsActivatedOrReloadedGC(invoiceVO)) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "10736"); actionInProgress = false; return; } // Check if any Gift Cards are eligible for Cash Payout on the invoice if (GiftCardBL.doesInvoiceContainBarcodedNAPAGiftCardReturnItem(invoiceVO)) { clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "10742"); actionInProgress = false; return; } if (!processPO()) { actionInProgress = false; return; } if (processAttention(save)) { finalizeBaseDialog.btnReturnToInvoice.dispatchEvent(pressTabKey(finalizeBaseDialog)); finalizeBaseDialog.lblErrorMsg.setText(strAttentionRequired); actionInProgress = false; return; } } private boolean canPerformSaveExpressCheckoutButtonAction() { if (finalizeBaseDialog.sqfPaymentsTendered != null && finalizeBaseDialog.sqfPaymentsTendered.getCorrespondingList() != null && finalizeBaseDialog.sqfPaymentsTendered.getCorrespondingList().getModel() != null && finalizeBaseDialog.sqfPaymentsTendered.getCorrespondingList().getModel() .getSize() > 0) { final InvoicePaymentVO payment = (InvoicePaymentVO) invoiceListModel.getData().get(0); if (payment != null) { if (payment.getTenderTypeID().intValue() == RefTenderType.NAPA_ONLINE || customerVO.getBillTypeCode() .equalsIgnoreCase(RefBillingType.CHARGE_ONLY)) { return true; }else{ return false; } } } return true; } /** * This method is used from base classes to perform some common activities. * To make all four controllers to use this method following methods are * used so that all controllers work. * * saveInvoice : This method saves invoice to data base. Phone room has * its own implementation. Rest use base class method. * handleException : This method is used to handle exception. Phone room * has its own implementation. Rest use base class method. * @param save */ protected void saveInvoice(boolean save) { finalizeBaseDialog.lblErrorMsg.setText(""); getDeliveryInfo(); getAttnPOMiscTaxInfo(); InvoiceVO invoice = (InvoiceVO) getModel(); InvoicingProfileVO invoicingProfileVO = (invoiceVO!=null && invoiceVO.isPhoneRoomMessagesFlag())? getRemoteInvoicingProfileVO():getInvoicingProfile(); try { if (invoice != null) { if(invoice.isPhoneRoomMessagesFlag()){ invoice.setSavedInvoiceType(TsoConstant.CALL_CENTER_SAVED_INVOICE); }else{ invoice.setSavedInvoiceType(TsoConstant.NORMAL_SAVED_INVOICE); } invoice.setTransactionNumber(null); if(isBopisInvoice){ removeRewardLineItemIfExists(); } if (isNapaRewardProgram) { removeRewardLineItemIfExists(); if (isStartTransactionSuccessful && request != null) { request.setTransactionIdentifier(populateTransactionIdentifierArray()); request.setCorrelationId(getCorrelationID()); if(isNapaRewardsProgramVersion2Active) { request.setLineItems(getLoyaltyEligibleLineItems(invoiceVO)); } loyaltyProgramService.cancelTransaction(request); } invoice.setLoyaltyCustomerLookup(loyaltyCustomerLookup); invoice.setLoyaltyCustomerExternalIdentifier(loyaltyCustomerExternalIdentifier); invoice.setRefLoyaltyCustomerStatusId(refLoyaltyCustomerStatusId); loyaltyCustomerLookup = null; } else if (invoicingProfileVO!=null && invoicingProfileVO.getUseNAPARewards() .booleanValue()) { invoice.setRefLoyaltyCustomerStatusId(new Byte( RefLoyaltyCustomerStatus.INELIGIBLE)); } if (saveInvoice(invoice, save)) { SwingUtilities.invokeLater(new Runnable() { public void run() { pointOfSaleEventDispatcher .fireInvoiceSaved(new InvoiceEvent(this, new InvoiceVO())); if (clientApplicationContext.getPOSState() .getState() == POSStateVO.CASHIER) { pointOfSaleEventDispatcher .fireChangedToCashier(null); } finalizeBaseDialog.btnReturnToInvoice .dispatchEvent(pressTabKey(finalizeBaseDialog)); finalizeBaseDialog.setVisible(false); } }); } } } catch (ApplicationException ae) { handleException(invoice, ae); } } /** * This method saves invoice to data base. Phone room has its * own implementation. Rest use base class method. * @param invoice * @param save * @return * @throws ApplicationException */ protected boolean saveInvoice(InvoiceVO invoice, boolean save) throws ApplicationException { return InvoiceBL.saveInvoice(invoice, customerVO, finalizeBaseDialog); } /** * This method is used to handle exception. Phone room * has its own implementation. Rest use base class method. * @param invoice * @param ae */ protected void handleException(InvoiceVO invoice, ApplicationException ae) { actionInProgress = false; logger.error(ae.toString(), ae); clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, ae.getUserMessageID(), ae.getUserMessageParameters()); } /** * This method checks if the tender type used is Charge. * @return true if Charge payment is used. */ private boolean isChargeOnAccount() { if (invoiceListModel.getData() == null || invoiceListModel.getData().size() <= 0 ) { return false; } final InvoicePaymentVO payment = (InvoicePaymentVO) invoiceListModel .getData().get(0); if (payment == null) { return false; } final Byte tenderTypeID = payment.getTenderTypeID(); if (tenderTypeID == null) { return false; } return (tenderTypeID.intValue() == RefTenderType.CHARGE_ON_ACCOUNT); } /** * This method checks if an Ithaca printer is selected. To make all four * controllers to use this method following method is used so that all * controllers work. * * isIthaca : This method checks if printer model type is Ithaca. All * four controllers has implementation of this method. * @return true if Ithaca is selected. */ private boolean isIthacaPrinterSelected() { Object o = finalizeBaseDialog.cbPrinter.getSelectedItem(); if ((o == null) || (!(o instanceof PrinterVO))) { return false; } PrinterVO selectedPrinter = (PrinterVO) o; byte printerModel = selectedPrinter.getRefPrinterModelID(); byte invoiceFormType = 0; try { invoiceFormType = clientApplicationContext.getInvoiceDAO() .getRefInvoiceFormTypeId(loc.intValue(), selectedPrinter.getID()); } catch (ApplicationException aerr) { logger.error(aerr.toString(), aerr); } return isIthaca(printerModel,invoiceFormType); } /** * This method performs action from Primary Tax combo box. To make all four * controllers to use this method following methods are used so that all * controllers work. * * getPrimaryTaxTableVO : This method retrieves Primary Tax Table * from data base. Phone room has its own * implementation. Rest use base class * method. * getSecondaryTaxTableVO : This method retrieves Secondary Tax * Table from data base. Phone room has its * own implementation. Rest use base class * method. * populateTaxInformation : This method populates InvoiceVO with * Primary Tax Information. Phone room has * its own implementation. Rest use base * class method. * populateSecondaryTaxInformation : This method populates InvoiceVO with * Secondary Tax Information. Phone room has * its own implementation. Rest use base * class method. */ private void processCbTax1() { Short taxIndex = null; boolean isPrimaryAsSecondary = false; IDValuePairVO item = (IDValuePairVO) finalizeBaseDialog.cbTax1 .getSelectedItem(); if (item != null) { if ((invoiceVO.getPrimaryTaxTableVO() != null && invoiceVO.getPrimaryTaxTableID() != null && invoiceVO .getPrimaryTaxTableID().shortValue() > 0) && (!invoiceVO.getPrimaryTaxTableVO().getID() .equals(item.getID()) || !invoiceVO .getPrimaryTaxTableVO() .getID() .equals(originalInvoiceVo.getPrimaryTaxTableVO() .getID()))) { taxIndex = (Short) item.getID(); TaxTableVO taxTableVO = getPrimaryTaxTableVO(false, taxIndex); populateTaxInformation(taxIndex, taxTableVO); TaxTableVO secondaryTaxTableVO = getSecondaryTaxTableVO(taxTableVO); if (invoiceVO.getManualTransaction().booleanValue()) { finalizeBaseDialog.fldTax2.setText(invoiceVO .getTaxAmount2().toString()); } else { finalizeBaseDialog.dlblTax2.setText(Tax .getTaxTableDisplayString(secondaryTaxTableVO)); } if (invoiceVO.getSecondaryTaxTableVO() == null) { isPrimaryAsSecondary = true; } invoiceVO.setSecondaryTaxTableVO(secondaryTaxTableVO); if (secondaryTaxTableVO == null) { populateSecondaryTaxInformation(secondaryTaxTableVO); } else { if (isPrimaryAsSecondary) { Tax.recalculateTaxableSales( invoiceVO, true, (customerVO.getAlternateCoreCustomerID() == null), clientApplicationContext.getApplicationType() == ClientApplicationContext.TAMS_II, Profile.POINT_OF_SALE_CLIENT, customerVO); setPrimaryAsSecondary(); } populateSecondaryTaxInformation(secondaryTaxTableVO); finalizeBaseDialog.fldTax2.setText(invoiceVO .getTaxAmount2().toString()); enableTax2(true); } if ((originalInvoiceVo.getPrimaryTaxTableVO() != null && originalInvoiceVo.getPrimaryTaxTableVO().getID() != null && originalInvoiceVo .getPrimaryTaxTableVO().getID().shortValue() > 0) && (originalInvoiceVo.getPrimaryTaxTableVO().getID() .equals(item.getID()))) { resetTaxDecision(); resetTaxInfo(); Tax.recalculateTaxableSales( invoiceVO, false, (customerVO.getAlternateCoreCustomerID() == null), clientApplicationContext.getApplicationType() == ClientApplicationContext.TAMS_II, Profile.POINT_OF_SALE_CLIENT, customerVO); } else { Tax.recalculateTaxableSales( invoiceVO, true, (customerVO.getAlternateCoreCustomerID() == null), clientApplicationContext.getApplicationType() == ClientApplicationContext.TAMS_II, Profile.POINT_OF_SALE_CLIENT, customerVO); if (invoiceVO.getSecondaryTaxTableVO() != null && invoiceVO.getSecondaryTaxTableVO().getID() != null && originalInvoiceVo.getSecondaryTaxTableVO() != null && originalInvoiceVo.getSecondaryTaxTableVO() .getID() != null && invoiceVO .getSecondaryTaxTableVO() .getID() .equals(originalInvoiceVo .getSecondaryTaxTableVO().getID()) && isDeliveryChecked()) { resetSecondaryTaxDecision(); } } } } calculateMiscAdjustments(); calculateInvoiceTotal(); } /** * This method retrieves Primary Tax Table from data base. Phone room * has its own implementation. Rest use base class method. * @param checkBeforeRetrieving * @param taxIndex * @return */ protected TaxTableVO getPrimaryTaxTableVO(boolean checkBeforeRetrieving, Short taxIndex) { return clientApplicationContext.getSystemDAO().getTaxTable(loc, taxIndex); } /** * This method retrieves Secondary Tax Table from data base. Phone * room has its own implementation. Rest use base class method. * @param taxTableVO * @return */ protected TaxTableVO getSecondaryTaxTableVO(TaxTableVO taxTableVO) { return Tax.getSecondaryTaxTableVO(taxTableVO); } /** * This method populates InvoiceVO with Primary Tax Information. * Phone room has its own implementation. Rest use base class * method. * @param taxIndex * @param taxTableVO */ protected void populateTaxInformation(Short taxIndex, TaxTableVO taxTableVO) { invoiceVO.setPrimaryTaxTableID(taxIndex); invoiceVO.setPrimaryTaxTableVO(taxTableVO); invoiceVO.setTaxPercent1(taxTableVO.getSalesTaxPercent()); } /** * This method populates InvoiceVO with Secondary Tax Information. * Phone room has its own implementation. Rest use base class * method. * @param taxTableVO */ protected void populateSecondaryTaxInformation(TaxTableVO taxTableVO) { if (taxTableVO != null) { invoiceVO.setSecondaryTaxTableID(taxTableVO.getID()); invoiceVO.setTaxPercent2(taxTableVO.getSalesTaxPercent()); } else { invoiceVO.setSecondaryTaxTableID(null); invoiceVO.setTaxPercent2(BD_ZERO); } } /** * This method performs business from cbTax1 field for a manual invoice. * To make all four controllers to use this method following method is * used so that all controllers work. * * isDeliveryChecked : This method checks if delivery is applied . All * four controllers implement this method. */ private void processManualCbTax1() { logger.debug("inside processManualCbTax1"); Short taxIndex = null; boolean isPrimaryAsSecondary = false; IDValuePairVO item = (IDValuePairVO) finalizeBaseDialog.cbTax1 .getSelectedItem(); if (item != null) { if ((invoiceVO.getPrimaryTaxTableVO() != null && invoiceVO.getPrimaryTaxTableID() != null && invoiceVO .getPrimaryTaxTableID().shortValue() > 0) && (!invoiceVO.getPrimaryTaxTableVO().getID() .equals(item.getID()) || !invoiceVO .getPrimaryTaxTableVO() .getID() .equals(originalInvoiceVo.getPrimaryTaxTableVO() .getID()))) { taxIndex = (Short) item.getID(); TaxTableVO taxTableVO = clientApplicationContext.getSystemDAO() .getTaxTable(loc, taxIndex); invoiceVO.setPrimaryTaxTableID(taxIndex); invoiceVO.setPrimaryTaxTableVO(taxTableVO); invoiceVO.setTaxPercent1(taxTableVO.getSalesTaxPercent()); // calculate the secondary tax... TaxTableVO secondaryTaxTableVO = Tax .getSecondaryTaxTableVO(taxTableVO); if (invoiceVO.getManualTransaction().booleanValue()) { finalizeBaseDialog.fldTax2.setText(invoiceVO .getTaxAmount2().toString()); } else { finalizeBaseDialog.dlblTax2.setText(Tax .getTaxTableDisplayString(secondaryTaxTableVO)); } if (invoiceVO.getSecondaryTaxTableVO() == null) { isPrimaryAsSecondary = true; } invoiceVO.setSecondaryTaxTableVO(secondaryTaxTableVO); if (secondaryTaxTableVO == null) { invoiceVO.setSecondaryTaxTableID(null); invoiceVO.setTaxPercent2(BD_ZERO); } else { if (isPrimaryAsSecondary) { Tax.recalculateTaxableSales( invoiceVO, true, (customerVO.getAlternateCoreCustomerID() == null), clientApplicationContext.getApplicationType() == ClientApplicationContext.TAMS_II, Profile.POINT_OF_SALE_CLIENT, customerVO); setPrimaryAsSecondary(); } invoiceVO.setSecondaryTaxTableID(secondaryTaxTableVO .getID()); invoiceVO.setTaxPercent2(secondaryTaxTableVO .getSalesTaxPercent()); finalizeBaseDialog.fldTax2.setText(invoiceVO .getTaxAmount2().toString()); enableTax2(true); } if ((originalInvoiceVo.getPrimaryTaxTableVO() != null && originalInvoiceVo.getPrimaryTaxTableVO().getID() != null && originalInvoiceVo .getPrimaryTaxTableVO().getID().shortValue() > 0) && (originalInvoiceVo.getPrimaryTaxTableVO().getID() .equals(item.getID()))) { resetTaxDecision(); resetTaxInfo(); Tax.recalculateTaxableSales( invoiceVO, false, (customerVO.getAlternateCoreCustomerID() == null), clientApplicationContext.getApplicationType() == ClientApplicationContext.TAMS_II, Profile.POINT_OF_SALE_CLIENT, customerVO); } else { Tax.recalculateTaxableSales( invoiceVO, true, (customerVO.getAlternateCoreCustomerID() == null), clientApplicationContext.getApplicationType() == ClientApplicationContext.TAMS_II, Profile.POINT_OF_SALE_CLIENT, customerVO); if (invoiceVO.getSecondaryTaxTableVO() != null && invoiceVO.getSecondaryTaxTableVO().getID() != null && originalInvoiceVo.getSecondaryTaxTableVO() != null && originalInvoiceVo.getSecondaryTaxTableVO() .getID() != null && invoiceVO .getSecondaryTaxTableVO() .getID() .equals(originalInvoiceVo .getSecondaryTaxTableVO().getID()) && isDeliveryChecked()) { resetSecondaryTaxDecision(); } } InvoiceVO tmpInvoiceVO = invoiceVO; Tax.calculateTaxAmounts( tmpInvoiceVO, customerVO, clientApplicationContext.getApplicationType() == ClientApplicationContext.TAMS_II); logger.debug("*** processManualCbTax1, setting dlblTax1Amount = " + tmpInvoiceVO.getTaxAmount1().toString()); finalizeBaseDialog.dlblTax1Amount.setText(tmpInvoiceVO .getTaxAmount1().toString()); } } } /** * This method performs business on Primary Tax field. */ private void processFldTax1() { if (finalizeBaseDialog.fldTax1.getText() != null && !finalizeBaseDialog.fldTax1.getText().equals("")) { BigDecimal tax1 = new BigDecimal(finalizeBaseDialog.fldTax1 .getText().trim()); if (!invoiceVO.getTaxAmount1().equals(tax1)) { invoiceVO.setTaxAmount1(tax1); } calculateInvoiceTotal(); if (invoiceVO.getManualTransaction().booleanValue()) { finalizeBaseDialog.lstPaymentMethod.setEnabled(true); finalizeBaseDialog.sqfPaymentMethod.setEnabled(true); } } } /** * This method performs business on Secondary Tax field. */ private void processFldTax2() { BigDecimal tax2 = new BigDecimal(finalizeBaseDialog.fldTax2.getText() .trim()); if (!invoiceVO.getTaxAmount2().equals(tax2)) { invoiceVO.setTaxAmount2(tax2); } calculateInvoiceTotal(); } /** * This method set payment panel based on payment selected. To make all four * controllers to use this method following method is used so that all * controllers work. * * getCustomerCardOnFile : This method returns null for all controller except * phone room controller. Only phone room controller * has specific implementation. * @param id * @return */ private int convertPaymentMethod(int id) { int newIndex = DEFAULTPANEL; int fleetCadId = 0; if (id == RefTenderTypeCategory.FLEET_CARD) { fleetCadId = id; id = RefTenderTypeCategory.CREDIT_CARD; } switch (id) { case RefTenderTypeCategory.CASH: paymentController.setCashCustomerVO(customerVO); newIndex = CASHPANEL; break; case RefTenderTypeCategory.EASY_PAY: newIndex = EASY_PAY_PANEL; break; case RefTenderTypeCategory.CREDIT_CARD: paymentController.setCreditCardPanel(invoiceVO, customerVO, getCustomerCardOnFile(),fleetCadId); newIndex = CREDITCARDPANEL; break; case RefTenderTypeCategory.CHARGE_ON_ACCOUNT: if ((invoiceListModel.getData() != null) && (invoiceListModel.getData().size() > 0)) { finalizeBaseDialog.lstPaymentMethod.clearSelection(); finalizeBaseDialog.sqfPaymentMethod.setText(""); logger.debug("Cannot select Charge On Account with other payment methods"); clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "1282"); } else { InvoicePaymentVO invPayVO = new InvoicePaymentVO(); invPayVO.setLOC(loc); invPayVO.setTenderTypeID(new Byte( (byte) RefTenderType.CHARGE_ON_ACCOUNT)); invPayVO.setAmountTendered(invoiceVO.getInvoiceTotal()); invPayVO.setAmountApplied(invoiceVO.getInvoiceTotal()); pointOfSaleEventDispatcher.firePaymentAdded(new PaymentEvent( this, invPayVO)); invoiceVO.setInvoicePayments(invoiceListModel.getData()); } newIndex = DEFAULTPANEL; break; case RefTenderTypeCategory.CHECK: paymentController.setCustomerStateCD(customerVO.getState()); newIndex = CHECKPANEL; break; case RefTenderTypeCategory.COUPON: newIndex = COUPONPANEL; break; case RefTenderTypeCategory.GIFT_CERTIFICATE: newIndex = GIFTCERTIFICATEPANEL; break; case RefTenderTypeCategory.NAPA_GIFT_CARD: paymentController.setInvoiceVO(invoiceVO); newIndex = NAPA_GIFT_CARD_PANEL; break; case RefTenderTypeCategory.ELECTRONIC_FUND_TRANSFER: newIndex = ELECTRONIC_FUND_TRANSFER; break; default: newIndex = DEFAULTPANEL; break; } return newIndex; } /** * This method returns null for all controller except phone room * controller. Only phone room controller has specific * implementation. * * @return customer cards. */ protected Vector getCustomerCardOnFile() { return null; } /** * This method checks the validity of delivery charge and set * required fields. * * @return true if delivery charge is valid. */ private boolean checkDeliveryCharge() { String tmp = finalizeBaseDialog.fldDeliveryCharge.getText(); if (tmp.startsWith("@")) { finalizeBaseDialog.fldDeliveryCharge.setText(""); return false; } logger.debug("inside checkDeliveryCharge, charge= " + tmp); try { double deliveryChargeValue = Double.parseDouble(tmp); } catch (NumberFormatException nfe) { finalizeBaseDialog.fldDeliveryCharge.setText(""); return false; } BigDecimal bdDeliveryCharge = new BigDecimal(tmp); if (InvoiceBL.isPriceExceedsMaxUnitPrice(bdDeliveryCharge)) { return false; } if (bdDeliveryCharge.abs().compareTo(new BigDecimal("99999999.99")) == 1) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "2218"); return false; } bdDeliveryCharge = bdDeliveryCharge.setScale(2, BigDecimal.ROUND_HALF_UP); finalizeBaseDialog.fldDeliveryCharge.setText(bdDeliveryCharge .toString()); finalizeBaseDialog.dlblDeliveryCharge.setText(bdDeliveryCharge .toString()); invoiceVO.setDeliveryCharge(bdDeliveryCharge); calculateInvoiceTotal(); return true; } /* * (non-Javadoc) * * @see * com.gpc.client.common.event.PaymentListener#paymentAdded(com.gpc.client * .common.event.PaymentEvent) * To make all four controllers to use this method following methods are * used so that all controllers work. * * setBalanceDue : This method set balanceDue in Payment Controller. Only * Regular controller implement this method. Rest all use * base class empty implementation. * addPayment : This method initiate a Thread to perform business. * Regular controller has its own implementation. Phone * room and Non phone room override this method to * eventually call base class method inside a condition. * Rest use base class implementation. */ public void paymentAdded(PaymentEvent pe) { logger.debug(": ENTER paymentAdded() "); resetNonTotalComponents(); getPaymentInfo((InvoicePaymentVO) pe.getModel()); logger.debug(": bdBalanceDue=" + bdBalanceDue.doubleValue()); logger.debug(": subtotal=" + invoiceVO.getSubTotal()); enablePanel(); paymentSelected = -1; setBalanceDue(); checkFlagsAndSetButtons(); addPayment(pe); } /** * This method initiate a Thread to perform business. Optional controller * has its own implementation. Phone room and Non phone room override * this method to eventually call base class method inside a condition. * Rest use base class implementation. * @param pe */ protected void addPayment(PaymentEvent pe) { SwingUtilities.invokeLater(new Runnable() { public void run() { logger.debug(": paymentAdded runLater. BalanceDue: " + bdBalanceDue.toString()); if (bdInvoiceTotal.compareTo(BD_ZERO) < 0) { if (bdBalanceDue.doubleValue() <= (double) 0.00) { finalizeBaseDialog.sqfPaymentsTendered .dispatchEvent(pressTabKey(finalizeBaseDialog.sqfPaymentsTendered)); } else { FocusManager.getCurrentManager().processKeyEvent(finalizeBaseDialog.cbTax1,new KeyEvent( finalizeBaseDialog.cbTax1, KeyEvent.KEY_PRESSED, new Date().getTime(), 0, KeyEvent.VK_TAB, '\t')); } } else { if (bdBalanceDue.doubleValue() >= (double) 0.00) { finalizeBaseDialog.sqfPaymentsTendered .dispatchEvent(pressTabKey(finalizeBaseDialog.sqfPaymentsTendered)); } else { FocusManager.getCurrentManager().processKeyEvent(finalizeBaseDialog.cbTax1,new KeyEvent( finalizeBaseDialog.cbTax1, KeyEvent.KEY_PRESSED, new Date().getTime(), 0, KeyEvent.VK_TAB, '\t')); } } } }); } /** * This method adds two amount. * @param oldCashAmt * @param AddtionalCashAmt * @return the consolidated amount */ private BigDecimal consolidateAmounts(BigDecimal oldCashAmt, BigDecimal AddtionalCashAmt) { if (oldCashAmt == null) { return AddtionalCashAmt; } if (AddtionalCashAmt == null) { return oldCashAmt; } return oldCashAmt.add(AddtionalCashAmt); } /** * This method returns cash payment record * @param vPayments * @return the cash payment record. */ private InvoicePaymentVO getCashPaymentRecord(Vector vPayments) { InvoicePaymentVO retValue = null; if (vPayments == null || vPayments.size() == 0) { return null; } int iCount = vPayments.size(); InvoicePaymentVO invoicePaymentVO = null; for (int i = 0; i < iCount; i++) { invoicePaymentVO = (InvoicePaymentVO) vPayments.elementAt(i); if (invoicePaymentVO.getTenderTypeID().intValue() == RefTenderType.CASH) { retValue = invoicePaymentVO; break; } } return retValue; } /** * This method update InvoicePaymentVO with amountTendered and amountApplied. * @param amountTendered * @param amountApplied */ private void updateCashPaymentDisplayValue(BigDecimal amountTendered, BigDecimal amountApplied) { logger.debug("=====>> ENTER updateCashPaymentDisplayValue amountTendered = " + amountTendered + ", amountApplied = " + amountApplied); int iRows = finalizeBaseDialog.lstPaymentsTendered.getModel().getSize(); int cashIndex = -1; InvoicePaymentVO invoicePaymentVO = null; for (int i = 0; (i < iRows); i++) { invoicePaymentVO = (InvoicePaymentVO) finalizeBaseDialog.lstPaymentsTendered .getModel().getElementAt(i); if (invoicePaymentVO.getTenderTypeID() != null && invoicePaymentVO.getTenderTypeID().intValue() == RefTenderType.CASH) { invoicePaymentVO.setAmountTendered(amountTendered); invoicePaymentVO.setAmountApplied(amountApplied); cashIndex = i; break; } } if (cashIndex != -1) { invoiceListModel.set(cashIndex, invoicePaymentVO); } } /** * This method retrieves the payment information. To make all four controllers * to use this method following method is used so that all controllers work. * * setPrinter : This method is used to cbPrinter index based on tender type * used. Phone room controller has empty implementation for it. * Rest all use base controller method. * @param invPayVO */ public void getPaymentInfo(InvoicePaymentVO invPayVO) { logger.debug(": ENTER getPaymentInfo : " + invPayVO); if (invPayVO == null) { return; } logger.debug(": invoicePaymentVO is: " + invPayVO.getInfo()); logger.debug(": invoiceVO: " + invoiceVO.getInfo()); int paymentType = invPayVO.getTenderTypeID().intValue(); setPrinter(paymentType); InvoicePaymentVO cashPaymentAlreadyEntered = null; if (paymentType != RefTenderType.CHARGE_ON_ACCOUNT) { BigDecimal bdZero = BD_ZERO; if (invoiceVO.getInvoiceTotal().compareTo(bdZero) < 0) { logger.debug(": invoice is < 0, customer must sign refund: " + strMustSignRefund); finalizeBaseDialog.lblErrorMsg.setText(strMustSignRefund); } } if (paymentType == RefTenderType.CASH) { // Consolidate the Cash payments if necessary cashPaymentAlreadyEntered = getCashPaymentRecord(invoiceListModel .getData()); if (cashPaymentAlreadyEntered != null) { cashPaymentAlreadyEntered.setAmountTendered(consolidateAmounts( cashPaymentAlreadyEntered.getAmountTendered(), invPayVO.getAmountTendered())); cashPaymentAlreadyEntered.setAmountApplied(consolidateAmounts( cashPaymentAlreadyEntered.getAmountApplied(), invPayVO.getAmountApplied())); updateCashPaymentDisplayValue( cashPaymentAlreadyEntered.getAmountTendered(), cashPaymentAlreadyEntered.getAmountApplied()); calculateAndDisplayAmountTendered_And_InvoiceTotals(); return; } } /* * If we did not ask the user to enter Customer Postal Code in Payment * Panel, get it from customerVO. */ if (invPayVO.getCustomerZipCode() == null || invPayVO.getCustomerZipCode().trim().length() == 0) { invPayVO.setCustomerZipCode(customerVO.getPostalCode()); } logger.debug(": adding payment to invoiceListModel"); invoiceListModel.getData().add(invPayVO); finalizeBaseDialog.lstPaymentsTendered.setListData(invoiceListModel .getData()); calculateAndDisplayAmountTendered_And_InvoiceTotals(); } /** * This method is used to cbPrinter index based on tender type used. Phone * room controller has empty implementation for it. Rest all use base * controller method. * @param paymentType */ protected void setPrinter(int paymentType) { if (paymentType == RefTenderType.CHARGE_ON_ACCOUNT) { defaultPrinterID = terminalVO.getChargeInvoicePrinterID(); } else { defaultPrinterID = terminalVO.getCashInvoicePrinterID(); } logger.debug("**** getPaymentInfo: defaultPrinterID= " + defaultPrinterID); finalizeBaseDialog.cbPrinter .setSelectedIndex(getPrinterIndex(defaultPrinterID)); } /* * (non-Javadoc) * * @see * com.gpc.client.common.event.PaymentListener#paymentCleared(com.gpc.client * .common.event.PaymentEvent) */ public void paymentCleared(PaymentEvent pe) { logger.debug(": ENTER: paymentCleared()"); enablePanel(); paymentSelected = -1; finalizeBaseDialog.lstPaymentMethod.clearSelection(); finalizeBaseDialog.sqfPaymentMethod.requestFocus(); } /* * (non-Javadoc) * * @see * com.gpc.client.common.event.PaymentListener#bopisPaymentFailure(com.gpc.client * .common.event.PaymentEvent) */ public void bopisPaymentFailure(PaymentEvent pe, String status) { logger.debug(": ENTER: bopisPaymentFailure()"); BOPISLogger.getInstance().setStoreProfile(invoiceVO.getLOC()).addBOPISLog(Constants.DEBUG, ": ENTER: bopisPaymentFailure()"); if (status != null && !status.equalsIgnoreCase("")) { if (status.equalsIgnoreCase("false")) { ClientApplicationContext.getClientApplicationContext() .getMessageMgr().showMessage(finalizeBaseDialog, "10130"); paymentController.displayPaymentPanel(DEFAULTPANEL); localFunding(pe); } else if (status.equalsIgnoreCase("TIMEOUT")) { BOPISLogger.getInstance().setStoreProfile(invoiceVO.getLOC()).addBOPISLog(Constants.DEBUG, "BOPIS Payment failed"); paymentController.getPnlPayment().lblErrorMessage.setText("BOPIS Payment failed"); delegateToAllowRetryAndLocalFunding(pe); } } } public void localFunding(PaymentEvent pe) { bopisPaymentFailed = true; logger.debug(": ENTER: bopisPaymentFailure()"); BOPISLogger.getInstance().setStoreProfile(invoiceVO.getLOC()).addBOPISLog(Constants.DEBUG, ": ENTER: bopisPaymentFailure()"); paymentController.isBopisInvoice(false); isBopisInvoice = false; removePaymentTendered(); removeRewardLineItemIfExists(); finalizeBaseDialog.dlblRewards.setText(BD_ZERO.toString()); logger.debug(" adding cash to payment list"); BOPISLogger.getInstance().setStoreProfile(invoiceVO.getLOC()).addBOPISLog(Constants.DEBUG, "adding cash to payment list"); Locale applicationLocale = clientApplicationContext.getCurrentLocale(); if(applicationLocale==null){ applicationLocale=Locale.getDefault(); } Vector vData = new Vector(); Vector paymentList = getPaymentTypeList(false, applicationLocale); for (int i = 0; i < paymentList.size(); i++) { RefTableVO refTableVO = (RefTableVO) paymentList.elementAt(i); vData.add(new IDValuePairVO(refTableVO.getID(), refTableVO .getDescription())); } if (customerVO.getBillTypeCode().equals(RefBillingType.CHARGE_ONLY)) { skipPaymentMethod = true; InvoicePaymentVO invPayVO = new InvoicePaymentVO(); invPayVO.setTenderTypeID(new Byte( (byte) RefTenderType.CHARGE_ON_ACCOUNT)); invPayVO.setLOC(invoiceVO.getLOC()); invPayVO.setAmountTendered(invoiceVO.getInvoiceTotal()); invPayVO.setAmountApplied(invoiceVO.getInvoiceTotal()); /*pointOfSaleEventDispatcher.firePaymentAdded(new PaymentEvent(this, invPayVO, isDispatchRequired()));*/ finalizeBaseDialog.lblPaymentMethod.setEnabled(false); finalizeBaseDialog.lblSequenceNumber.setEnabled(false); finalizeBaseDialog.sqfPaymentsTendered.setEnabled(false); finalizeBaseDialog.btnRemove.setEnabled(false); paymentController.displayPaymentPanel(DEFAULTPANEL); } else finalizeBaseDialog.lstPaymentMethod.setListData(vData); finalizeBaseDialog.dlblTotalAmtTendered.setText(""); invoiceVO.setRewardAmount(BD_ZERO); calculateInvoiceTotal(); paymentCleared(pe); //If Napa rewards is set, populate the Napa rewards dialog. Thread paymentThread = delegateSetInitialData(); InvoicingProfileVO invoicingProfileVO = null; if(null!=invoiceVO && invoiceVO.isPhoneRoomMessagesFlag()) { invoicingProfileVO = getRemoteInvoicingProfileVO(); } else { invoicingProfileVO = getInvoicingProfile(); } logger.debug("UseNapaRewards Flag: " + invoicingProfileVO.getUseNAPARewards().booleanValue()); BOPISLogger.getInstance().setStoreProfile(invoiceVO.getLOC()).addBOPISLog(Constants.INFO, "UseNapaRewards Flag: " + invoicingProfileVO.getUseNAPARewards().booleanValue()); isNapaRewardProgram = invoicingProfileVO.getUseNAPARewards().booleanValue() && !invoiceVO.getManualTransaction().booleanValue() && customerVO.getREFNAPACustomerCategoryID().intValue() == (RefNAPACustomerCategory.RETAIL_DIY) && !(clientApplicationContext.isLoggedInAsPhoneRoom() && (isPhoneRoomMessageCheckout() || isRemoteStore())); try { napaRewardsNonEligibleList = clientApplicationContext .getInvoiceDAO().getNapaRewardsNonEligibleList(); BOPISLogger.getInstance().setStoreProfile(invoiceVO.getLOC()).addBOPISLog(Constants.INFO, "napaRewardsNonEligibleList: " + napaRewardsNonEligibleList); } catch (ApplicationException applicationException) { logger.error(applicationException.getMessage(), applicationException); BOPISLogger.getInstance().setStoreProfile(invoiceVO.getLOC()).errorBOPISLog(applicationException.getMessage(), applicationException); } updateLoyaltyEligibleForLineItem(); if (isNapaRewardProgram) { removeRewardLineItemIfExists(); Thread esbThread = delegateToESBRegistration(paymentThread); if (esbThread != null) { esbThread.start(); } } else { if (paymentThread != null) { paymentThread.start(); } } if (clientApplicationContext.getProfile(Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()).getStoreProfile().getPhoneRoomInUse().booleanValue()) { if (!clientApplicationContext.isLoggedInAsPhoneRoom()) { finalizeBaseDialog.btnErase.setEnabled(false); } } } /* * (non-Javadoc) * * @see * com.gpc.client.common.event.PaymentListener#paymentPanelDisplayed(com * .gpc.client.common.event.PaymentEvent) */ public void paymentPanelDisplayed(PaymentEvent pe) { disablePanel(); finalizeBaseDialog.cbPrinter.setEnabled(false); } /** * This method launch payment controller based on payment selected. * * @param selectedItem The selected payment method. */ private void selectPaymentMethod(final int selectedItem) { //if payment method selected using seq# in left panel, need to hide the right panel if(RefStoreConfigurationUtil.isRefundTenderRestrictionEnabled()) { if(invoiceVO != null && invoiceVO.getInvoiceTotal().signum() < 0) { payPanel.pnlTenderTypes.setVisible(false); } } paymentSelected = convertPaymentMethod(selectedItem); if (paymentSelected != DEFAULTPANEL) { paymentController.setBalanceDue(bdBalanceDue.negate()); SwingUtilities.invokeLater(new Runnable() { public void run() { paymentController.displayPaymentPanel(paymentSelected,selectedItem); } }); logger.debug("=====>> Calling invoiceVO.setInvoicePayments!"); invoiceVO.setInvoicePayments(invoiceListModel.getData()); } } /** * This method calculate amount tendered. Only optional controller has * its own implementation. Rest all use base class implementation. * @return */ protected BigDecimal calculateAmountTendered() { logger.debug(": ENTER: calculateAmountTendered()"); bdAmtTendered = BD_ZERO.setScale(2, BigDecimal.ROUND_HALF_UP); int iPayments = invoiceListModel.getData().size(); InvoicePaymentVO p = null; for (int i = 0; i < iPayments; i++) { p = (InvoicePaymentVO) invoiceListModel.getData().elementAt(i); if (p.getAmountTendered() != null) { bdAmtTendered = bdAmtTendered.add(p.getAmountTendered()); } } BOPISLogger.getInstance().setStoreProfile(invoiceVO.getLOC()).addBOPISLog(Constants.INFO, "calculateAmountTendered(): " + bdAmtTendered); logger.debug(": EXIT: calculateAmountTendered: " + bdAmtTendered); return bdAmtTendered; } /** * This method calculate amount tendered. Functional implementation of this method and * 'calculateAmountTendered' methods are same. 'calculateAmountTendered' is the latest * implementation. But 'FinalizeOptionalDeliveryInvoiceController.java' still needs * to use 'reComputeAmountTendered'. Hence it is still present. In near future, when * 'Optional delivery checkout' is also implemented with IPC, this method can be removed and * 'calculateAmountTendered' method can be used instead. * @return */ protected BigDecimal reComputeAmountTendered() { bdAmtTendered = BD_ZERO; int iPayments = invoiceListModel.getData().size(); InvoicePaymentVO p = null; for (int i = 0; i < iPayments; i++) { p = (InvoicePaymentVO) invoiceListModel.getData().elementAt(i); if (p.getAmountTendered() != null) { bdAmtTendered = bdAmtTendered.add(p.getAmountTendered()); } } bdAmtTendered = bdAmtTendered.setScale(2, BigDecimal.ROUND_HALF_UP); return bdAmtTendered; } /** * This method calculate and display amount tendered and invoice total. To make * all four controllers to use this method following method is used so that all * controllers work. * * calculateAmountTendered : This method calculate amount tendered. Only regular * controller has its own implementation. Rest all use * base class implementation. */ protected void calculateAndDisplayAmountTendered_And_InvoiceTotals() { logger.debug(": ENTER calculateAndDisplayAmountTendered_And_InvoiceTotals."); String amtTendered = calculateAmountTendered().toString(); logger.debug(": amtTendered: " + amtTendered); BOPISLogger.getInstance().setStoreProfile(invoiceVO.getLOC()).addBOPISLog(Constants.INFO, ": amtTendered: " + amtTendered); finalizeBaseDialog.dlblTotalAmtTendered.setText(amtTendered); calculateInvoiceTotal(); } /** * This method make the dialog visible. To make all four controllers to use * this method following methods are used so that all controllers work. * closeIfNapaGiftCardExists : This method closes the dialog if a charge * only customer has transacted for napa gift * card. Regular checkout controller has * empty implementation. Rest all use base * class method. * @param visibility true if dialog needs to be visible */ public void setViewVisible(boolean visibility) { if (finalizeBaseDialog != null) { finalizeBaseDialog.setVisible(visibility); } else { logger.error(" finalizeDialog is NULL !!!"); } } /** * This method set cbDeliveryPriority if Delivery is enabled. To make all * four controllers to use this method following method is used so that * all controllers work. * * isDeliveryChecked : This method checks if delivery is applied . All * four controllers implement this method. * @param priorityID */ protected void enableDelivery(int priorityID) { logger.debug("---- inside enableDelivery, priorityID= " + priorityID); if (isDeliveryChecked()) { // if there is a default priority, set to that value. if (priorityID >= 0) { finalizeBaseDialog.cbDeliveryPriority .setSelectedIndex(searchPriority(priorityID)); } else { // set to 'Not Assigned' finalizeBaseDialog.cbDeliveryPriority.setSelectedIndex(0); } } } /** * This method searches priority in cbDeliveryPriority. * * @param id The priority id to be searched. * * @return The index of priority in cbDeliveryPriority. */ private int searchPriority(int id) { int retValue = 0; int iCount = finalizeBaseDialog.cbDeliveryPriority.getItemCount(); if (iCount > 0) { Integer priorityID = null; for (int i = 0; i < iCount; i++) { if (!finalizeBaseDialog.cbDeliveryPriority.getItemAt(i) .toString().equals(notAssigned)) { priorityID = (Integer) ((IDValuePairVO) finalizeBaseDialog.cbDeliveryPriority .getItemAt(i)).getID(); if (priorityID.intValue() == id) { retValue = i; break; } } } } return retValue; } /** * This method validates Attention entry. * * @return true if validation pass. */ protected boolean validateAttention() { // if customer number is zero, the attention field is required. boolean attentionRequired = false; boolean isValid = true; Integer zero = new Integer(0); StoreProfileVO storeProfile = getStoreProfile(); if ((customerVO.getCustomerNumber().compareTo(zero) == 0) || ((storeProfile != null && storeProfile.getPhoneRoomInUse() .booleanValue()) && (clientApplicationContext .getProfile(Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()) .getInvoicingProfile().getAttentionEntryRequired() .booleanValue()))) { attentionRequired = true; } if (attentionRequired) { String attention = finalizeBaseDialog.fldAttention.getText(); if ((attention == null) || (attention.equals(""))) { isValid = false; } } return isValid; } /** * This method loads blanket PO to cbPONumber. To make all four controllers to * use this method following methods are used so that all controllers work. * * getBlanketPOList : This method retrieve blanket PO from * database. Phone room controller has its own * implementation to load data from remote * store. Rest all use base class method. * * isBlanketPORequiredToBeRemoved : This method checks whether blanket PO can * be removed. Phone room controller has its * own implementation which return 'false'. * Rest all use base class method. */ private void loadBlanketPO() { finalizeBaseDialog.cbPONumber.removeActionListener(this); Vector vBlanketPOList = new Vector(); try { vBlanketPOList = getBlanketPOList(); } catch (ApplicationException aerr) { logger.error(aerr.toString(), aerr); clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, aerr.getUserMessageID(), aerr.getUserMessageParameters()); return; } // go through the list of Blanket PO's and pick out the ones that have // a Max amount allowed that's equal to or more than the invoice total. if (vBlanketPOList == null || vBlanketPOList.isEmpty()) { blanketPO = null; return; } Object o = null; finalizeBaseDialog.cbPONumber.removeAllItems(); CustomerBlanketPOVO customerBlanketPoVo = null; for (int i = vBlanketPOList.size() - 1; i > -1; i--) { o = vBlanketPOList.elementAt(i); if (o == null) { vBlanketPOList.removeElementAt(i); continue; } customerBlanketPoVo = (CustomerBlanketPOVO) o; if (isBlanketPORequiredToBeRemoved(customerBlanketPoVo)) { vBlanketPOList.removeElementAt(i); } else { finalizeBaseDialog.cbPONumber.addItem(customerBlanketPoVo); } }// end of for loop if (!vBlanketPOList.isEmpty()) { finalizeBaseDialog.cbPONumber.setSelectedIndex(0); blanketPO = (CustomerBlanketPOVO) finalizeBaseDialog.cbPONumber .getSelectedItem(); } else { finalizeBaseDialog.cbPONumber.addActionListener(this); } String poNumber = ((JTextField) finalizeBaseDialog.cbPONumber .getEditor().getEditorComponent()).getText(); if (poNumber == null || poNumber.trim().length() == 0) { loadAttentionAndPOInfo(); } } /** * This method retrieve blanket PO from database. Phone room controller * has its own implementation to load data from remote store. Rest all * use base class method. * @return * @throws ApplicationException */ protected Vector getBlanketPOList() throws ApplicationException { return clientApplicationContext.getCustomerDAO().getCustomerBlanketPO( loc, invoiceVO.getCustomerID(), invoiceVO.getCustomerTypeCD()); } /** * This method checks whether blanket PO can be removed. Phone room * controller has its own implementation which return 'false'. Rest * all use base class method. * @param customerBlanketPoVo * @return */ protected boolean isBlanketPORequiredToBeRemoved( CustomerBlanketPOVO customerBlanketPoVo) { return InvoiceBL.isBlanketPOExpired(customerBlanketPoVo) || (customerBlanketPoVo.getMaximumAmountAllowed() != null && customerBlanketPoVo .getMaximumAmountAllowed().compareTo( invoiceVO.getInvoiceTotal()) < 0); } /** * New version of calculateMiscAdjust to loop through invoiceLines * and calculate the Misc Adjust for each line * @param miscAdjust */ protected void calculateMiscAdjust(BigDecimal miscAdjust) { InvoiceBL.calculateMiscAdjustments(invoiceVO, miscAdjust, customerVO.getAlternateCoreCustomerID() != null // indicate the // BL to apply // misc adj // separately // for main and // core ); finalizeBaseDialog.dlblMiscAdjustments.setText(invoiceVO .getMiscAdjustments().toString()); } /** * This method calculates invoice total. To make all four controllers to use * this method following methods are used so that all controllers work. * * isDeliveryChecked : This method checks if delivery is applied. * All four controllers implement this method. * calculateSpecificInvoiceTotal : This method calculates invoice total which * are not common across all controller. * Phone room controller implement this method * to eventually call base class method from * inside a condition. * enableSaveButton : This method enable save button. Only phone * room controller has its implementation. Rest * all use base class empty implementation. */ protected void calculateInvoiceTotal() { logger.debug(": ENTER: calculateInvoiceTotal()"); bdAmtTendered = bdAmtTendered.setScale(2, BigDecimal.ROUND_HALF_UP); // Calculate our tax, taxes are not calculate for NAPA Online customers. logger.debug(": bdAmtTendered: " + bdAmtTendered); BOPISLogger.getInstance().setStoreProfile(invoiceVO.getLOC()).addBOPISLog(Constants.INFO, ": bdAmtTendered: " + bdAmtTendered); calculateTaxAmounts(); // code setting tax/non-tax amounts to zero for a transfer customer // has been moved to InvoiceBL to be called immediately before posting. // Calculate what our total should be bdInvoiceTotal = bdInvoiceSubtotal; if (isDeliveryChecked()) { bdInvoiceTotal = bdInvoiceTotal.add(invoiceVO.getDeliveryCharge()); } bdInvoiceTotal = bdInvoiceTotal.add(invoiceVO.getMiscAdjustments()); logger.debug("calculateInvoiceTotals, added TaxAmount1= " + invoiceVO.getTaxAmount1().toString()); bdInvoiceTotal = bdInvoiceTotal.add(invoiceVO.getTaxAmount1()); bdInvoiceTotal = bdInvoiceTotal.add(invoiceVO.getTaxAmount2()); if (isNapaRewardProgram || (isBopisInvoice )){ bdInvoiceTotal = bdInvoiceTotal.add(invoiceVO.getRewardAmount()); if (isBopisInvoice) { logger.error("FinalizeInvoiceBaseController:calculateInvoiceTotals, added reward amount= " + invoiceVO.getRewardAmount()); logger.error("FinalizeInvoiceBaseController: bdInvoiceTotal: " + bdInvoiceTotal); } } bdInvoiceTotal = bdInvoiceTotal.setScale(2, BigDecimal.ROUND_HALF_UP); logger.debug(": bdInvoiceTotal: " + bdInvoiceTotal); // if charge only update table calculateSpecificInvoiceTotal(); logger.debug(": computing balance due."); computeAndDisplayBalanceDue(); handleLoyaltyMiscAndDelCharges(); boolean readyToPrint = isInvoicePaidInFull() || CustomerBL.isNapaOnlineCustomer(customerVO); logger.debug(": should Print button be enabled? " + readyToPrint); finalizeBaseDialog.btnPrint.setEnabled(readyToPrint); logger.debug(": calculateInvoiceTotal(): invoice total: " + bdInvoiceTotal); if (isBopisInvoice) { logger.error("FinalizeInvoiceBaseController:BOPIS invoice: calculateInvoiceTotal(): invoice total: " + bdInvoiceTotal); } enableSaveButton(); handleDisplayInvoiceSummary(bdInvoiceTotal); invoiceVO.setInvoiceTotal(bdInvoiceTotal); } /** * This method calculate amount applied. Only optional controller has * its own implementation. Rest all use base class implementation. * @return */ protected BigDecimal calculateAmountApplied() { logger.debug(": ENTER: calculateAmountApplied()"); BigDecimal bdAmtApplied = BD_ZERO.setScale(2, BigDecimal.ROUND_HALF_UP); int iPayments = invoiceListModel.getData().size(); InvoicePaymentVO p = null; for (int i = 0; i < iPayments; i++) { p = (InvoicePaymentVO) invoiceListModel.getData().elementAt(i); if (p.getAmountApplied() != null) { bdAmtApplied = bdAmtApplied.add(p.getAmountApplied()); } } logger.debug(": EXIT: calculateAmountApplied: " + bdAmtApplied); return bdAmtApplied; } /** * This method calculates invoice total which are not common across * all controller. Phone room controller implement this method to * eventually call base class method from inside a condition. */ protected void calculateSpecificInvoiceTotal() { if ((customerVO.getBillTypeCode().equals(RefBillingType.CHARGE_ONLY) || (CustomerBL .isCOD(customerVO) && invoiceVO.getSubTotal().compareTo( MathUtil.BD_ZERO) < 0)) && invoiceListModel.size() > 0) { InvoicePaymentVO ipVO = (InvoicePaymentVO) invoiceListModel.get(0); ipVO.setAmountTendered(bdInvoiceTotal); invoiceListModel.set(0, ipVO); bdAmtTendered = bdInvoiceTotal; finalizeBaseDialog.dlblTotalAmtTendered.setText(bdAmtTendered .toString()); logger.debug(": charge-only subtree on calculateInvoiceTotal. Setting amtTendered to: " + bdAmtTendered); } } /** * This is used to check whether secondary tax is applicable or not. * * @return A boolean value to indicate secondary tax is applicable or not */ protected boolean isSecondaryTaxApplicable() { TaxTableVO secondaryTaxTableVO = null; Short selectedTaxTableId = null; boolean secondaryTaxApplicable = false; if ((invoiceVO.getPrimaryTaxTableVO() != null && invoiceVO.getPrimaryTaxTableID() != null && invoiceVO .getPrimaryTaxTableID().shortValue() > 0)) { TaxTableVO taxTableVO = getPrimaryTaxTableVO(true, invoiceVO .getPrimaryTaxTableID()); secondaryTaxTableVO = getSecondaryTaxTableVO(taxTableVO); } IDValuePairVO selectedTaxTable = (IDValuePairVO) finalizeBaseDialog.cbTax1 .getSelectedItem(); if (selectedTaxTable != null) { selectedTaxTableId = (Short) selectedTaxTable.getID(); TaxTableVO taxTableVO = getPrimaryTaxTableVO(true, selectedTaxTableId); secondaryTaxTableVO = getSecondaryTaxTableVO(taxTableVO); } if (secondaryTaxTableVO != null && secondaryTaxTableVO.getID() != null && secondaryTaxTableVO.getID().shortValue() > 0) { secondaryTaxApplicable = true; } return secondaryTaxApplicable; } /** * This method prepares DisplayableInvoiceVO. * @param invoiceTotal */ protected void handleDisplayInvoiceSummary(BigDecimal invoiceTotal) { logger.debug(": handleDisplayInvoiceSummary: " + invoiceTotal); if (invoiceVO.doDisplayPricing()) { logger.debug(": doDisplayPricing is true"); try { if (invoiceTotal == null) { dispInvVO.setDeliveryCharge(null); dispInvVO.setMiscAdj(null); dispInvVO.setTaxAmount1(null); dispInvVO.setTaxAmount2(null); dispInvVO.setTotal(null); } else { if (dispInvVO.getTotal() != null && invoiceTotal.compareTo(dispInvVO.getTotal()) == 0) { return; } dispInvVO.setDeliveryCharge(invoiceVO.getDeliveryCharge()); dispInvVO.setMiscAdj(invoiceVO.getMiscAdjustments()); dispInvVO.setTaxAmount1(invoiceVO.getTaxAmount1()); if (invoiceVO.getPrimaryTaxTableVO() != null && invoiceVO.getPrimaryTaxTableVO() .getSecondaryTaxTableID() != null && invoiceVO.getPrimaryTaxTableVO() .getSecondaryTaxTableID().shortValue() > 0) { dispInvVO.setTaxAmount2(invoiceVO.getTaxAmount2()); } else { dispInvVO.setTaxAmount2(null); } } dispInvVO.setTotal(invoiceTotal); logger.debug(": displayInvoiceVO is: " + dispInvVO.toString()); if (getRMIClient() != null) { getRMIClient().displayInvoiceSummary(dispInvVO); } } catch (RemoteException re) { // do nothing. we have already displayed a warning. let them // keep invoicing } } } /** * This method calculates the primary tax, it calls the calculatePrimaryTax * method from FinalizeInvoiceBL, then displayed the calculated primary tax. * To make all four controllers to use this method following method is used * so that all controllers work. * * isForcePost : : This method determines whether invoice require force post. * Current Regular and Optional controller has its * implementation. Phone room and Non Phone room return true * as default value. */ protected void calculateTaxAmounts() { BigDecimal bdZero = BD_ZERO; if (!invoiceVO.getManualTransaction().booleanValue() || (invoiceVO.getManualTransaction().booleanValue() && ((finalizeBaseDialog.fldTax1 .getText() == null) || finalizeBaseDialog.fldTax1 .getText().equals("")))) { logger.debug("calculateTaxAmounts, calling Tax.calculateTaxAmounts"); // recalculateTaxableSales must always be called before calculate // Tax amounts Tax.recalculateTaxableSales( invoiceVO, false, (customerVO.getAlternateCoreCustomerID() == null), clientApplicationContext.getApplicationType() == ClientApplicationContext.TAMS_II, Profile.POINT_OF_SALE_CLIENT, customerVO); Tax.calculateTaxAmounts( invoiceVO, customerVO, clientApplicationContext.getApplicationType() == ClientApplicationContext.TAMS_II); // Correct amount differences (cents) between Sales ticket & Stamped Invoice final InvoicingProfileVO invoicingProfileVO = getInvoicingProfile(); if (invoicingProfileVO != null && invoicingProfileVO.getRefElectronicInvoiceVendorId() != null && invoicingProfileVO.getRefElectronicInvoiceVendorId().intValue() == 1 && doesInvoiceTaxAmountCorrectionRequired(invoiceVO, customerVO)) { reCalculateInvoiceTaxAmount(invoiceVO, customerVO); } } logger.debug("calculateTaxAmounts, getTaxAmount1= " + invoiceVO.getTaxAmount1().toString()); finalizeBaseDialog.dlblTax1Amount.setText(invoiceVO.getTaxAmount1() .toString()); if (isSecondaryTaxApplicable()) { logger.debug("calculateTaxAmounts, getTaxAmount2= " + invoiceVO.getTaxAmount2().toString()); finalizeBaseDialog.dlblTax2Amount.setText(invoiceVO.getTaxAmount2() .toString()); } else { invoiceVO.setTaxAmount2(bdZero); finalizeBaseDialog.dlblTax2Amount.setText(bdZero.toString()); } // for manual invoice, we only want to use what is entered, so if fldTax // is empty, // we set taxAmount to zero. if (invoiceVO.getManualTransaction().booleanValue()) { if ((finalizeBaseDialog.fldTax1.getText() == null) || finalizeBaseDialog.fldTax1.getText().equals("")) { // Note this doesn't apply manager approved force post. if (!isForcePost()) { invoiceVO.setTaxAmount1(bdZero); } } else { BigDecimal taxAmnt1 = new BigDecimal(finalizeBaseDialog.fldTax1 .getText().toString()); invoiceVO.setTaxAmount1(taxAmnt1); } } logger.debug("calculateTaxAmounts: calling Tax.recalculateTaxableSales "); } /** * This method takes a string date and converts it to a Date object. * @param stringDate date in string form. * @return java.util.Date */ public Date parseDate(String stringDate) { Integer dateFormat = new Integer(clientApplicationContext .getProfile(Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()) .getStoreProfile().getRefDateFormatId().intValue()); FwoPattern fwoDatePattern = (FwoDatePattern) FwoPattern .getDatePatternInstance( clientApplicationContext.getCurrentLocale(), dateFormat); Date parsedDate = null; try { parsedDate = (Date) fwoDatePattern.parse(stringDate); } catch (PatternParseException ppe) { return null; } return parsedDate; } /** * This method takes a string date and converts it to a Date object. * To make all four controllers to use this method following method * is used so that all controllers work. * * prepareTimeToParse : This method perform few action on string and * return it.Current Regular and Optional has * same implementation. Rest return the string * passed. * @param stringTime time in string form * @return java.uti.Date */ public Date parseTime(String stringTime) { logger.debug("parseTime(" + stringTime + ")"); stringTime = prepareTimeToParse(stringTime); Date dateTime = null; FwoPattern fwoTimePattern = (FwoTimePattern) FwoPattern .getTimePatternInstance(locale); String parsedTime = ""; try { parsedTime = fwoTimePattern.format(stringTime); // logger.info("parsedTime: " + parsedTime); } catch (PatternFormatException pfe) { logger.info(pfe.toString(), pfe); } try { dateTime = (Date) fwoTimePattern.parse(parsedTime, locale); } catch (PatternParseException ppe) { logger.info(ppe.toString(), ppe); } return dateTime; } /** * This method loads InvoiceDeliveryVO if delivery is selected.To make all * four controllers to use this method following method is used so that * all controllers work. * * isDeliveryChecked :This method checks if delivery is applied . All * four controllers implement this method. */ private void getDeliveryInfo() { if (isDeliveryChecked()) { invoiceDeliveryVO = new InvoiceDeliveryVO(); invoiceVO.setDeliveryFlag(Boolean.TRUE); String deliveryMethod = finalizeBaseDialog.fldDeliveryMethod .getText(); String storeLanguageCd = getStoreProfile().getRefLanguageCd(); String storeCountryCd = getStoreProfile().getRefCountryCd(); Locale storeLocale = new Locale(storeLanguageCd.toLowerCase(), storeCountryCd); String localizedDeliveryMethod = clientApplicationContext .getResourceBundleReader().getLocalizedText( ResourceBundleReader.UI, getDialogName() + ".fldDeliveryMethod", storeLocale); if (defaultDelivery.equals(deliveryMethod)) { invoiceDeliveryVO .setDeliveryDescription(localizedDeliveryMethod); } else { invoiceDeliveryVO.setDeliveryDescription(deliveryMethod); } if (finalizeBaseDialog.rbDeliveryPriority.isSelected()) { int index = finalizeBaseDialog.cbDeliveryPriority .getSelectedIndex(); logger.debug("--- delivery priority selected= " + index); BOPISLogger.getInstance().setStoreProfile(invoiceVO.getLOC()).addBOPISLog(Constants.INFO, "--- delivery priority selected= " + index); if (clientApplicationContext.getSystemDAO().isNotAssignedNull() .booleanValue()) { logger.debug("--- isNotAssignedNull = true"); BOPISLogger.getInstance().setStoreProfile(invoiceVO.getLOC()).addBOPISLog(Constants.INFO, "--- isNotAssignedNull = true"); if (finalizeBaseDialog.cbDeliveryPriority.getSelectedItem() .toString().trim().equals(notAssigned)) { logger.debug("--- item selected = Not Assigned"); BOPISLogger.getInstance().setStoreProfile(invoiceVO.getLOC()).addBOPISLog(Constants.INFO, "--- item selected = Not Assigned"); invoiceDeliveryVO.setDeliveryPriorityID(null); } else { logger.debug("--- item selected id= " + ((IDValuePairVO) finalizeBaseDialog.cbDeliveryPriority .getSelectedItem()).getID().toString()); invoiceDeliveryVO .setDeliveryPriorityID(new Byte( ((IDValuePairVO) finalizeBaseDialog.cbDeliveryPriority .getSelectedItem()).getID() .toString())); } } else { logger.debug("--- isNotAssignedNull = false"); BOPISLogger.getInstance().setStoreProfile(invoiceVO.getLOC()).addBOPISLog(Constants.INFO, "--- isNotAssignedNull = false"); invoiceDeliveryVO .setDeliveryPriorityID(new Byte( ((IDValuePairVO) finalizeBaseDialog.cbDeliveryPriority .getSelectedItem()).getID() .toString())); } } else { Calendar calDelivery = Calendar .getInstance(clientApplicationContext .getCurrentLocale()); Calendar calTime = Calendar .getInstance(clientApplicationContext .getCurrentLocale()); // set the requested delivery date String strDeliveryDate = finalizeBaseDialog.fldDeliveryDate .getText(); if ((strDeliveryDate != null) && (!strDeliveryDate.equals(""))) { Date deliveryDate = parseDate(strDeliveryDate); calDelivery.setTime(deliveryDate); // set the requested delivery time String strDeliveryTime = finalizeBaseDialog.fldDeliveryTime .getText(); Date deliveryTime = parseTime(strDeliveryTime); if (deliveryTime != null) { calTime.setTime(deliveryTime); } calDelivery.set(calDelivery.get(Calendar.YEAR), calDelivery.get(Calendar.MONTH), calDelivery.get(Calendar.DATE), calTime.get(Calendar.HOUR_OF_DAY), calTime.get(Calendar.MINUTE), calTime.get(Calendar.SECOND)); invoiceDeliveryVO.setRequestedDeliveryDate(calDelivery .getTime()); invoiceDeliveryVO.setDeliveryDate(null); } } invoiceDeliveryVO.setInvoiceID(invoiceVO.getID()); invoiceDeliveryVO.setLOC(invoiceVO.getLOC()); if (defaultDelivery.equals(deliveryMethod)) { invoiceDeliveryVO .setDeliveryDescription(localizedDeliveryMethod); } else { invoiceDeliveryVO.setDeliveryDescription(deliveryMethod); } if (customerDeliveryVO != null) { invoiceDeliveryVO.setDeliveryRouteCD(customerDeliveryVO .getDeliveryRouteCD()); } if (customerDeliveryVO != null) { invoiceDeliveryVO.setTravelMinutes(customerDeliveryVO .getTravelTimeCustomer()); } invoiceVO.setInvoiceDeliveryVO(invoiceDeliveryVO); } else { invoiceVO.setDeliveryFlag(Boolean.FALSE); invoiceVO.setInvoiceDeliveryVO(null); } } /** * This method set PO, Attention and Tax information to InvoiceVO. * To make all four controllers to use this method following * method is used so that all controllers work. * * isNonEmpty : This method checks if the argument passed is empty. * Current Phone room controller has specific * implementation. Rest all return default value as * 'true'. */ private void getAttnPOMiscTaxInfo() { String poNumber = ((JTextField) finalizeBaseDialog.cbPONumber .getEditor().getEditorComponent()).getText(); if (poNumber != null && poNumber.length() > 0) { invoiceVO.setPONumber(poNumber); } else { invoiceVO.setPONumber(null); } invoiceVO.setAttention(finalizeBaseDialog.fldAttention.getText()); invoiceVO .setPrimaryTaxTableID(invoiceVO.getPrimaryTaxTableVO().getID()); invoiceVO.setTaxPercent1(invoiceVO.getPrimaryTaxTableVO() .getSalesTaxPercent()); if (invoiceVO.getSecondaryTaxTableVO() == null) { invoiceVO.setSecondaryTaxTableID(null); invoiceVO.setTaxPercent2(BD_ZERO); } else { invoiceVO.setSecondaryTaxTableID(invoiceVO.getSecondaryTaxTableVO() .getID()); invoiceVO.setTaxPercent2(invoiceVO.getSecondaryTaxTableVO() .getSalesTaxPercent()); } } /** * This is a helper method to finalise a invoice. To make all four controllers * to use this method following methods are used so that all controllers work. * paymentAndInvoiceListModelConsistencyCheck : * This method logs if payment is empty. This is implemented by * Regular and Optional Checkout controller. Both Phone room and * Non Phone Room has empty implementation. * isInvoiceFromLocalStore : This method has business implementation only in * Phone room Checkout controller. Rest three controller * return 'true' as default value. * isProcessAfterPost : This method has business implementation only in Phone room * Checkout controller. Rest three controller return 'true' * as default value. * checkAndHandleDuplicatePayments : * This method has business implementation only in Regular * Checkout controller. Rest three controller return 'false' * as default value. * @param sendPayment * @param payments */ private void sendPaymentInfo(boolean sendPayment, Vector payments) { if (sendPayment) { logger.debug("sendPayment, calling checkForMultiplePayments"); checkForMultiplePayments(); finalizeBaseDialog.lblErrorMsg.setText(""); if (CustomerBL.isNapaOnlineCustomer(customerVO)) { InvoiceBL.splitNAPANotes(invoiceVO); } paymentAndInvoiceListModelConsistencyCheck(payments); if (customerVO.getAlternateCoreCustomerID() != null && !invoiceVO.getManualTransaction().booleanValue()) { // Check to ensure that at the time of finalizing an order, // the part invoice subtotal matches the sum of parts. reCalculateInvoiceTotal(invoiceVO); } //Gift Card V2 if(useNapaGCV2() && payments != null && payments.size() > 0) { if (!processGiftCardDebitTransaction(payments, false)) { actionInProgress = false; return; } // Refund credit invoice amount to Gift Card if (!GiftCardBL.refundCreditInvoiceAmountToGiftCard(payments, finalizeBaseDialog, invoiceVO.getSourceOrderId())) { actionInProgress = false; return; } } if (isBopisInvoice) { InvoicePaymentVO vo = (InvoicePaymentVO) payments.elementAt(0); if (vo.getTenderTypeID().intValue() == RefTenderType.NAPA_ONLINE) { vo.setTenderTypeID(new Byte((byte) RefTenderType.CHARGE_ON_ACCOUNT)); payments.set(0, vo); } isBopisInvoice = false; paymentController.isBopisInvoice(false); } invoiceVO.setInvoicePayments(payments); getDeliveryInfo(); getAttnPOMiscTaxInfo(); if (invoiceVO.getManualTransaction().booleanValue()) { if ((invoiceVO.getPrinterId() == null) || (invoiceVO.getPrinterId().intValue() <= 0)) { // If it is a manual invoice just send a valid invoice // printer to the service eventhough no actual print is // generated. invoiceVO.setPrinterId(new Integer( ((PrinterVO) finalizeBaseDialog.cbPrinter .getItemAt(0)).getID())); } } else { invoiceVO.setPrinterId(new Integer( ((PrinterVO) finalizeBaseDialog.cbPrinter .getSelectedItem()).getID())); if (customerVO.getAlternateCoreCustomerID() != null) { InvoiceBL.separateCoreItemsFromMainInvoice(invoiceVO, customerVO); } } // validate business rules for invoice finalization if (isBREInUse() && isChargeInvoice() && !isValidateBREInvoice()) { actionInProgress = false; return; } glassPane.setVisible(true); glassPane.addMouseListener(this); glassPane.requestFocus(); InvoicePaymentVO payment = (InvoicePaymentVO) invoiceVO.getInvoicePayments().elementAt(0); InvoicingProfileVO invoicingProfileVO = null; if(null!=invoiceVO && invoiceVO.isPhoneRoomMessagesFlag()) { invoicingProfileVO = getRemoteInvoicingProfileVO(); } else { invoicingProfileVO = getInvoicingProfile(); } if ("Y".equalsIgnoreCase(invoicingProfileVO.getUseSigPlus()) && invoicingProfileVO.getAllowChangeSigCaptureForChargeSale().booleanValue() && !CustomerBL.isTransferCustomer(customerVO) && !isDeliveryChecked() && payment.getTenderTypeID() != null && payment.getTenderTypeID().intValue() == RefTenderType.CHARGE_ON_ACCOUNT && (payment.getSignatureFile() == null || payment.getSignatureFile().length == 0)) { SwingUtilities.invokeLater(new Runnable() { public void run() { SignatureController signatureController= new SignatureController(finalizeBaseDialog); if (SignatureController.CLEAR.equals(signatureController.getAction())) { return; } else { if (SignatureController.OK.equals(signatureController.getAction())) { ((InvoicePaymentVO) invoiceVO.getInvoicePayments().elementAt(0)).setSignatureFile(signatureController.getSignatureVO().getBaos().toByteArray()); } callServiceInNewThread(); } } }); } else { callServiceInNewThread(); } } else { actionInProgress = false; } } private void callServiceInNewThread() { new Thread(new Runnable() { public void run() { // Deal the case of return to the phone room store boolean proceedAfterPost = false; InvoiceVO returnedInvoiceVO = null; boolean redoPmt = false; if(isNapaRewardProgram){ invoiceVO.setLoyaltyCustomerLookup(loyaltyCustomerLookup); invoiceVO.setLoyaltyCustomerExternalIdentifier(loyaltyCustomerExternalIdentifier); invoiceVO.setRefLoyaltyCustomerStatusId(refLoyaltyCustomerStatusId); invoiceVO.setLoyaltyInvoiceExternalIdentifier(loyaltyInvoiceExternalIdentifier); loyaltyCustomerLookup = null; } else if (getInvoicingProfile().getUseNAPARewards() .booleanValue()) { invoiceVO.setRefLoyaltyCustomerStatusId(new Byte( RefLoyaltyCustomerStatus.INELIGIBLE)); } if(request != null && (isStartTransactionSuccessful || (request.getLoyaltyEligibleAmount() != null && request.getLoyaltyEligibleAmount().signum() < 0))){ invoiceVO.setPhoneNumber(request.getPhoneNumber()); invoiceVO.setLoyaltyEligibleAmount(request.getLoyaltyEligibleAmount()); } // If not remote store, post invoice thru TAMS code if (isInvoiceFromLocalStore()) { returnedInvoiceVO = finalizeHandler.postAndPrint(); returnedInvVO = returnedInvoiceVO; logger.debug("FinalizeInvoiceBaseController.sendPaymentInfo - returnedInvoiceVO = " + returnedInvoiceVO); if (returnedInvoiceVO != null && returnedInvoiceVO.getCepdiStatusVO() != null) { final CEPDIStatusVO cepdiStatus = returnedInvoiceVO.getCepdiStatusVO(); logger.debug("EInvoice CEPDIStatus = " + cepdiStatus); if (cepdiStatus != null && cepdiStatus.getStatus() != null && cepdiStatus.getStatus().equalsIgnoreCase("true")) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "10104"); } else if (cepdiStatus != null && cepdiStatus.getErrorMessage() != null) { // If the RFC of the receiver does not exist in the list of RFCs // registered but not canceled by the SAT. if (isInvalidCustomerRFC(cepdiStatus)) { if (CustomerBL.isWalkInCustomer(customerVO)) { // R.F.C number is invalid. Please re-enter.\nYou have $1 attempts left. clientApplicationContext.getMessageMgr() .showMessage(finalizeBaseDialog, "10111", new String[] { cepdiStatus.getErrorMessage(), "2"}); SwingUtilities.invokeLater(new Runnable() { public void run() { displayCustomerInfoModalforNextAttempt(returnedInvVO); } }); } else { String storeManagerNotificationMessage = clientApplicationContext .getResourceBundleReader() .getLocalizedText(ResourceBundleReader.UI, "CustomerInfoDialog.managerNotifyMessage", clientApplicationContext.getCurrentLocale()); clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "10110", new String[] {storeManagerNotificationMessage + cepdiStatus.getErrorMessage() }); } } else if (CustomerBL.isWalkInCustomer(customerVO) && isInValidCustomerName(cepdiStatus)) { // Customer Name is invalid. Please re-enter.\nYou have $1 attempts // left. clientApplicationContext.getMessageMgr() .showMessage(finalizeBaseDialog, "10501", new String[] { cepdiStatus.getErrorMessage(), "2"}); SwingUtilities.invokeLater(new Runnable() { public void run() { displayCustomerInfoModalforNextAttempt(returnedInvVO); } }); } else if (CustomerBL.isWalkInCustomer(customerVO) && isInValidCustomerPostalCode(cepdiStatus)) { // Customer Postal Code is invalid. Please re-enter.\nYou have $1 // attempts left. clientApplicationContext.getMessageMgr() .showMessage(finalizeBaseDialog, "10502", new String[] { cepdiStatus.getErrorMessage(), "2"}); SwingUtilities.invokeLater(new Runnable() { public void run() { displayCustomerInfoModalforNextAttempt(returnedInvVO); } }); } else { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "10110", new String[] { cepdiStatus.getErrorMessage() }); } } } proceedAfterPost = isProcessAfterPost(returnedInvoiceVO); } else { proceedAfterPost = finalizeHandler .postInvoiceInServingStore(); if(invoiceVO.getSavedCart() != null){ try { InvoiceBL.saveInvoiceInServingStore(invoiceVO.getSavedCart(), customerVO, finalizeBaseDialog); } catch (ApplicationException applicationException) { /* * Not showing any message at this message. Need to show the message in immediate next * release. */ logger.error(applicationException.getMessage(), applicationException); } } returnedInvoiceVO = invoiceVO; } if (finalizeHandler.isPaymentExceptionOccured()) { SwingUtilities.invokeLater(new Runnable() { public void run() { clientApplicationContext.getMessageMgr() .showMessage(finalizeBaseDialog, "2204b"); finalizeBaseDialog.lblErrorMsg.setText(""); } }); if ((customerVO != null) && (customerVO.getBillTypeCode() != null) && !(customerVO.getBillTypeCode() .equalsIgnoreCase(RefBillingType.CHARGE_ONLY))) { removePaymentTendered(); } else { finalizeBaseDialog.cbPrinter .dispatchEvent(pressTabKey(finalizeBaseDialog.cbPrinter)); } proceedAfterPost = false; finalizeHandler.setPaymentExceptionOccured(false); } if (proceedAfterPost) { if (finalizeHandler.callCheckBalance() && finalizeHandler .getPostAndPrintErrorInvoiceVO() == null && finalizeHandler .getPostAndPrintErrorTenderType() == null && invoiceVO.getDuplicatedCardPaymentKeys() == null) { checkBalance(); } invoiceFinalized = true; if (finalizeHandler.callClosingSteps()) { doClosingSteps(); } InvoiceVO tmpInvVO = finalizeHandler .getPostAndPrintErrorInvoiceVO(); if (tmpInvVO != null && finalizeHandler .getPostAndPrintErrorTenderType() != null) { processPostAndPrintError(finalizeHandler .getPostAndPrintErrorInvoiceVO(), finalizeHandler .getPostAndPrintErrorTenderType()); finalizeHandler.setPostAndPrintErrorInvoiceVO(null); finalizeHandler .setPostAndPrintErrorTenderType(null); invoiceFinalized = false; } redoPmt = checkAndHandleDuplicatePayments(tmpInvVO); if (redoPmt) { invoiceVO.setDuplicatedCardPaymentKeys(null); } invoiceFinalized = redoPmt ? false : invoiceFinalized; if (returnedInvoiceVO != null) { InvoiceBL.closePpseSession(returnedInvoiceVO); } else { InvoiceBL.closePpseSession(invoiceVO); } } actionInProgress = false; if (!redoPmt) { try { SwingUtilities.invokeAndWait(new Runnable() { public void run() { glassPane.setVisible(false); glassPane .removeMouseListener(FinalizeInvoiceBaseController.this); } }); } catch (InterruptedException ie) { logger.error(ie.getMessage(), ie); } catch (InvocationTargetException inve) { logger.error(inve.getMessage(), inve); } } } }).start(); } /** * This method removes the duplicate IPC payment. * @param dupInvPmyVO InvoicePaymentVO * @return true if integrated transaction is void */ protected boolean removeDuplicatedIPCPayment(InvoicePaymentVO dupInvPmyVO) { logger.warn(" Entering to removeDuplicatedIPCPayment() method! Current System Time: " + new Date() + " Customer Num: " + customerVO.getCustomerNumber() + " Invoice Total: " + invoiceVO.getInvoiceTotal() + " Tender Type: " + dupInvPmyVO.getTenderTypeDesc()); boolean rtnVal = voidIntegratedTransaction(dupInvPmyVO); // remove the payment from invoiceListModel, then sync the model with // lstPaymentsTendered boolean foundInLstModel = false; InvoicePaymentVO testInvPmt = null; if (rtnVal) { // find dupInvPmyVO in invoiceListModel then remove it for (int k = 0; k < invoiceListModel.size(); k++) { testInvPmt = (InvoicePaymentVO) invoiceListModel.get(k); if (testInvPmt != null && testInvPmt.getIpcJournalKey() != null && testInvPmt.getIpcJournalKey().equals( dupInvPmyVO.getIpcJournalKey())) { invoiceListModel.remove(k); finalizeBaseDialog.lstPaymentsTendered.clearSelection(); foundInLstModel = true; logger.warn(" Found paymnt in invoiceListModel and removed!"); break; } } } logger.warn(" Found paymnt in invoiceListModel and removed = " + foundInLstModel); return rtnVal; } /** * This method make the dialog invisible. */ private void doClosingSteps() { SwingUtilities.invokeLater(new Runnable() { public void run() { pointOfSaleEventDispatcher.fireInvoicePrinted(new InvoiceEvent( this, new InvoiceVO())); if (clientApplicationContext.getPOSState().getState() == POSStateVO.CASHIER) { pointOfSaleEventDispatcher.fireChangedToCashier(null); } finalizeBaseDialog.setVisible(false); } }); } /** * This method process Post and Print Error.To make all four controllers * to use this method following methods are used so that all controllers * work. * * isInvoiceNumberPresent : This method checks if the invoice number is * present. Current Phone room controller * return default 'true'. Rest all use base * class business implementation. * isForcePost : This method determines whether invoice * require force post. Current Regular and * Optional controller has its implementation. * Phone room and Non Phone room return true * as default value. * @param errorInvoiceVO InvoiceVO * @param errorTenderType Byte */ private void processPostAndPrintError(InvoiceVO errorInvoiceVO, Byte errorTenderType) { logger.debug("=====>> ENTER processPostAndPrintError !!!"); // Get the modified Invoice object from the server invoiceVO = errorInvoiceVO; boolean haveAnInvoiceNumber = false; if (isInvoiceNumberPresent()) { haveAnInvoiceNumber = true; } boolean manualTRX = false; if ((invoiceVO != null) && invoiceVO.getManualTransaction().booleanValue()) { manualTRX = true; } // if ((haveAnInvoiceNumber) && (!(manulTRX && // !invoiceVO.isForcePost())) && !dupIpcPmts ) { if ((haveAnInvoiceNumber) && (!(manualTRX && !isForcePost()))) { // Disable and all fields on Finalze dialog disablePanel(); // Now enable only few elements on the Finalize dialog // Enable print, so that the user can try again. finalizeBaseDialog.btnPrint.setEnabled(true); logger.debug("===>> set btnPrint enabled !"); // Enable Payment components finalizeBaseDialog.lblPaymentMethod.setEnabled(true); finalizeBaseDialog.lstPaymentMethod.setEnabled(true); finalizeBaseDialog.lblPaymentMethodSequence.setEnabled(true); finalizeBaseDialog.sqfPaymentMethod.setEnabled(true); finalizeBaseDialog.lblPaymentsTendered.setEnabled(true); finalizeBaseDialog.lstPaymentsTendered.setEnabled(true); finalizeBaseDialog.lblSequenceNumber.setEnabled(true); finalizeBaseDialog.sqfPaymentsTendered.setEditable(true); finalizeBaseDialog.btnRemove.setEnabled(true); finalizeBaseDialog.lblAttention.setEnabled(true); finalizeBaseDialog.fldAttention.setEnabled(true); finalizeBaseDialog.lblPONumber.setEnabled(true); finalizeBaseDialog.cbPONumber.setEnabled(true); finalizeBaseDialog.cbPONumber.setEditable(true); finalizeBaseDialog.cbPrinter.setEnabled(true); } Vector payments = invoiceVO.getInvoicePayments(); Byte tenderTypeID = null; tenderTypeID = errorTenderType; InvoicePaymentVO paymentVOUsedForErroredTransaction = getErrorTransactionPayment(payments, tenderTypeID); if (paymentVOUsedForErroredTransaction != null) { if (selectPaymentTendered(paymentVOUsedForErroredTransaction)) { logger.debug("=====>> from processPostAndPrintError: call showPayment !"); showPayment(paymentVOUsedForErroredTransaction); } } checkFlagsAndSetButtons(); } /** * This method selects the payment method already tendered and * remove payment if customer is not charge only. * * @param p InvoicePaymentVO * @return true if successful. */ private boolean selectPaymentTendered(InvoicePaymentVO p) { if ((p == null) || (p.getTenderTypeID() == null)) { return false; } int selectedIndex = -1; for (int i = 0; i < invoiceListModel.getSize(); i++) { int paymentType = ((InvoicePaymentVO) invoiceListModel.get(i)) .getTenderTypeID().intValue(); if (paymentType == p.getTenderTypeID().intValue()) { selectedIndex = i; break; } } if (selectedIndex == -1) { return false; } finalizeBaseDialog.lstPaymentsTendered.setSelectedIndex(selectedIndex); if (!customerVO.getBillTypeCode().equals(RefBillingType.CHARGE_ONLY)) { removePayment(); } return true; } /** * This methods check for multiple payments. */ private void checkForMultiplePayments() { if (invoiceListModel.getData() != null && invoiceListModel.getData().size() > 1) { int cashIndex = 0; int checkIndex = 0; BigDecimal cashAmntTendered = BD_ZERO; BigDecimal checkAmntTendered = BD_ZERO; BigDecimal temp = BD_ZERO; if (invoiceVO.getInvoiceTotal().compareTo(BD_ZERO) > 0) { for (int i = 0; i < invoiceListModel.getData().size(); i++) { InvoicePaymentVO invPayVO = (InvoicePaymentVO) invoiceListModel .getData().elementAt(i); if (invPayVO.getTenderTypeID().intValue() == 0) { // Cash cashIndex = i; cashAmntTendered = invPayVO.getAmountTendered(); } else if (invPayVO.getTenderTypeID().intValue() == 2) { // Check checkIndex = i; checkAmntTendered = invPayVO.getAmountTendered(); } } // if check is written for more than the balance due, find cash back if (checkAmntTendered.compareTo(invoiceVO.getInvoiceTotal()) > 0) { BigDecimal cashBack = checkAmntTendered.subtract(invoiceVO .getInvoiceTotal()); // check if the cash paid is more than the amount of cash back if (cashAmntTendered.compareTo(cashBack) > 0) { temp = cashAmntTendered.subtract(cashBack); ((InvoicePaymentVO) invoiceListModel.getData().elementAt( cashIndex)).setAmountApplied(temp); ((InvoicePaymentVO) invoiceListModel.getData().elementAt( checkIndex)).setAmountApplied(checkAmntTendered); } else { temp = checkAmntTendered.subtract(cashBack); ((InvoicePaymentVO) invoiceListModel.getData().elementAt( checkIndex)).setAmountApplied(temp); ((InvoicePaymentVO) invoiceListModel.getData().elementAt( cashIndex)).setAmountApplied(cashAmntTendered); } } } } } /** * This method returns the InvoicePaymentVO of already made transaction. * @param v Vector of payments * @param tenderTypeID Tender type id. * @return InvoicePaymentVO of already made transaction. */ private InvoicePaymentVO getErrorTransactionPayment(Vector v, Byte tenderTypeID) { if (tenderTypeID == null) { return null; } int tenderType = tenderTypeID.intValue(); if ((v == null) || (v.size() == 0)) { return null; } InvoicePaymentVO retValue = null; int iCount = v.size(); Object o = null; InvoicePaymentVO temp = null; for (int i = 0; i < iCount; i++) { o = v.elementAt(i); if ((o == null) || (!(o instanceof InvoicePaymentVO))) { continue; } temp = (InvoicePaymentVO) o; if (temp.getTenderTypeID() == null) { continue; } if (tenderType != temp.getTenderTypeID().intValue()) { continue; } retValue = temp; break; } return retValue; } /** * This method launch payment controller. * @param o InvoicePaymentVO */ private void showPayment(InvoicePaymentVO o) { paymentVO = o; logger.debug("===== >> ENTER showPayment "); SwingUtilities.invokeLater(new Runnable() { public void run() { if ((paymentVO == null) || (paymentVO.getTenderTypeID() == null)) { return; } int tenderType = paymentVO.getTenderTypeID().intValue(); logger.debug("===== >> IN showPayment : tenderType = " + tenderType); switch (tenderType) { case RefTenderType.AMERICAN_EXPRESS: case RefTenderType.DISCOVER: case RefTenderType.MASTER_CARD: case RefTenderType.VISA: case RefTenderType.AMERICAN_EXPRESS_CORPORATE: case RefTenderType.PIN_DEBIT: logger.debug("===== >> IN showPayment : calling paymentController.setBalanceDue = " + bdBalanceDue.negate()); paymentController.setBalanceDue(bdBalanceDue.negate()); paymentController.displayPaymentPanel(CREDITCARDPANEL, paymentVO); break; case RefTenderType.CHECK: paymentController.setBalanceDue(bdBalanceDue.negate()); paymentController .displayPaymentPanel(CHECKPANEL, paymentVO); break; } } }); } /** * This method returns InvoicePaymentVO. * * @param billingTypeCD billing type of customer * @return InvoicePaymentVO */ private InvoicePaymentVO makePaymentVO(String billingTypeCD) { InvoicePaymentVO retValue = new InvoicePaymentVO(); BigDecimal bdCash = invoiceVO.getInvoiceTotal(); bdCash = bdCash.setScale(2, BigDecimal.ROUND_HALF_UP); retValue.setLOC(loc); retValue.setAmountTendered(bdCash); if (billingTypeCD.equals(RefBillingType.CHARGE_ONLY)) { retValue.setTenderTypeID(new Byte( (byte) RefTenderType.CHARGE_ON_ACCOUNT)); } else { retValue.setTenderTypeID(new Byte((byte) RefTenderType.CASH)); } return retValue; } /** * This method void the invoice. */ private void voidInvoice() { logger.debug("now doing voidInvoice...."); Vector payments = new Vector(); payments.add(makePaymentVO(customerVO.getBillTypeCode())); invoiceVO.setInvoicePayments(payments); invoiceVO.setPrinterId(new Integer( ((PrinterVO) finalizeBaseDialog.cbPrinter.getSelectedItem()).getID())); try { InvoiceBL.printAndVoidInvoice(invoiceVO, customerVO); pointOfSaleEventDispatcher.fireInvoicePrinted(new InvoiceEvent( this, new InvoiceVO())); if (clientApplicationContext.getPOSState().getState() == POSStateVO.CASHIER) { pointOfSaleEventDispatcher.fireChangedToCashier(null); } finalizeBaseDialog.setVisible(false); } catch (final NoPaymentFoundException noPaymentFoundException) { logger.error("No Payment Exception occured on ", noPaymentFoundException); SwingUtilities.invokeLater(new Runnable() { public void run() { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "2204b"); } }); if ((customerVO != null) && (customerVO.getBillTypeCode() != null) && !(customerVO.getBillTypeCode() .equalsIgnoreCase(RefBillingType.CHARGE_ONLY))) { removePaymentTendered(); } actionInProgress = false; finalizeBaseDialog.btnPrint.dispatchEvent(pressTabKey(finalizeBaseDialog.btnPrint)); } } /** * This method checks whether payments has cash payment. * * @return true if invoice has cash or if amount tendered is more * than amount applied. */ private boolean invoiceHasCash() { Vector payments = invoiceVO.getInvoicePayments(); for (int i = 0; i < payments.size(); i++) { InvoicePaymentVO payment = (InvoicePaymentVO) payments.get(i); if (payment.getTenderTypeID().intValue() == RefTenderType.CASH) { return true; } if (payment.getAmountTendered().doubleValue() > payment .getAmountApplied().doubleValue()) { return true; } } return false; } /** * This method check balance and clos the dialog. * * @return true if successful. */ private boolean checkBalance() { BigDecimal bdZero = BD_ZERO; bdZero = bdZero.setScale(2, BigDecimal.ROUND_HALF_UP); if ((invoiceVO.getInvoiceTotal().compareTo(bdZero) == 0) || (invoiceVO.getTransactionTypeID().intValue() == 2)) { SwingUtilities.invokeLater(new Runnable() { public void run() { pointOfSaleEventDispatcher .fireInvoicePrinted(new InvoiceEvent(this, new InvoiceVO())); if (clientApplicationContext.getPOSState().getState() == POSStateVO.CASHIER) { pointOfSaleEventDispatcher.fireChangedToCashier(null); } finalizeBaseDialog.setVisible(false); } }); return true; } InvoicingProfileVO invoicingProfileVO = null; if(null!=invoiceVO && invoiceVO.isPhoneRoomMessagesFlag()) { invoicingProfileVO = getRemoteInvoicingProfileVO(); } else { invoicingProfileVO = clientApplicationContext .getProfile(Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()) .getInvoicingProfile(); } logger.debug("askForAmountTendered= " + invoicingProfileVO.getAskForAmountTendered().booleanValue()); if (!invoicingProfileVO.getAskForAmountTendered().booleanValue()) { SwingUtilities.invokeLater(new Runnable() { public void run() { pointOfSaleEventDispatcher .fireInvoicePrinted(new InvoiceEvent(this, new InvoiceVO())); if (clientApplicationContext.getPOSState().getState() == POSStateVO.CASHIER) { pointOfSaleEventDispatcher.fireChangedToCashier(null); } finalizeBaseDialog.setVisible(false); } }); return true; } /** * @todo: implement for checks with cash back || * (((InvoicePaymentVO)vPaymentList.get(i)).getTenderTypeID() == * 2) && * clientApplicationContext.getProfile(Profile.POINT_OF_SALE_CLIENT * , * clientApplicationContext.getLocation()).getInvoicingProfile() * .getMaximumCashBack(). doubleValue() > 0; */ if (terminalVO.isCashDrawer() && invoiceHasCash()) { boolean isCashDrawerOpen = false; try { CashDrawer.open(); isCashDrawerOpen = true; } catch (IOException ie) { logger.error("Cannot open cash drawer because of IOException"); } catch (NoSuchPortException nspe) { logger.error("Cannot open cash drawer because of NoSuchPortException"); } catch (PortInUseException piue) { logger.error("Cannot open cash drawer because of PortInUseException"); } catch (UnsupportedCommOperationException ucoe) { logger.error("Cannot open cash drawer due to UnsupportedCommOperationException"); } if (!isCashDrawerOpen) { SwingUtilities.invokeLater(new Runnable() { public void run() { ClientApplicationContext.getClientApplicationContext() .getMessageMgr() .showMessage(finalizeBaseDialog, "2206"); } }); } } BigDecimal bdChangeDue = bdBalanceDue; bdChangeDue = bdChangeDue.setScale(2, BigDecimal.ROUND_HALF_UP); PaymentPanel payPanel = (PaymentPanel) paymentController.getView(); payPanel.lblRefundAmount.setText(bdChangeDue.toString()); if (invoiceVO.doDisplayPricing() && dispInvVO != null && bdChangeDue.floatValue() >= (float) 0.00) { dispInvVO.setChangeDue(bdChangeDue); try { if (getRMIClient() != null) { getRMIClient().displayChangeDue(dispInvVO); } } catch (RemoteException re) { // do nothing. we have already displayed a warning. let them // keep invoicing } } paymentController.displayPaymentPanel(REFUNDPANEL); disablePanel(); return false; } /* * (non-Javadoc) * * @see * com.gpc.client.common.event.InvoiceListener#invoiceCancelled(com.gpc. * client.common.event.InvoiceEvent) */ public void invoiceCancelled(InvoiceEvent ie) { clearList(); resetAttAndPO(); resetValues(); resetPanel(); paymentController.refreshLists(); loyaltyCustomerLookup = null; } public void invoiceSplitted(InvoiceEvent ie){} public void recallSavedInvoiceDialogueClosed(InvoiceEvent ie){} /* * (non-Javadoc) * * @see * com.gpc.client.common.event.PaymentListener#changeDue(com.gpc.client. * common.event.PaymentEvent) */ public void changeDue(PaymentEvent pe) { pointOfSaleEventDispatcher.fireInvoicePrinted(new InvoiceEvent(this, new InvoiceVO())); if (clientApplicationContext.getPOSState().getState() == POSStateVO.CASHIER) { pointOfSaleEventDispatcher.fireChangedToCashier(null); } finalizeBaseDialog.setVisible(false); } /** * This method performs action on click of Express Checkout button. * To make all four controllers to use this method following * methods are used so that all controllers work. * * isPODeliveryValidated : This method validates PO. Current Regular * and Optional Controller has common * implementation. Phone room and and Non * Phone room has common implementation. */ private void doExpressCheckout() { if (!isPODeliveryValidated(true)) { actionInProgress = false; return; } invoiceVO.setTransactionNumber(null); expressCheckoutController.setInitialData(); expressCheckoutController.setViewVisible(true); if (expressCheckoutController.isExpressCheckoutIDValid()) { if(isBopisInvoice){ removeRewardLineItemIfExists(); } if(isNapaRewardProgram){ removeRewardLineItemIfExists(); if (isStartTransactionSuccessful && request!=null){ request.setTransactionIdentifier(populateTransactionIdentifierArray()); request.setCorrelationId(getCorrelationID()); if(isNapaRewardsProgramVersion2Active) { request.setLineItems(getLoyaltyEligibleLineItems(invoiceVO)); } loyaltyProgramService.cancelTransaction(request); } invoiceVO.setLoyaltyCustomerLookup(loyaltyCustomerLookup); invoiceVO.setLoyaltyCustomerExternalIdentifier(loyaltyCustomerExternalIdentifier); invoiceVO.setRefLoyaltyCustomerStatusId(refLoyaltyCustomerStatusId); loyaltyCustomerLookup = null; } else if (getInvoicingProfile().getUseNAPARewards().booleanValue()) { invoiceVO.setRefLoyaltyCustomerStatusId(new Byte( RefLoyaltyCustomerStatus.INELIGIBLE)); } invoiceVO.setSavedInvoiceType(new Byte("2")); invoiceVO.setTransactionNumber(expressCheckoutController .getExpressCheckoutID()); getDeliveryInfo(); getAttnPOMiscTaxInfo(); InvoiceBL.closePpseSession(invoiceVO); try { if (InvoiceBL.saveInvoice((InvoiceVO) getModel(), customerVO, finalizeBaseDialog)) { SwingUtilities.invokeLater(new Runnable() { public void run() { pointOfSaleEventDispatcher .fireInvoiceSaved(new InvoiceEvent(this, new InvoiceVO())); finalizeBaseDialog.btnReturnToInvoice .dispatchEvent(pressTabKey(finalizeBaseDialog)); if (clientApplicationContext.getPOSState() .getState() == POSStateVO.CASHIER) { pointOfSaleEventDispatcher .fireChangedToCashier(null); } finalizeBaseDialog.setVisible(false); } }); } } catch (ApplicationException aerr) { logger.error(aerr.toString(), aerr); clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, aerr.getUserMessageID(), aerr.getUserMessageParameters()); } } else { actionInProgress = false; finalizeBaseDialog.btnReturnToInvoice .dispatchEvent(pressTabKey(finalizeBaseDialog)); } } /** * This method perform action on click of Remove button. To make all four controllers * to use this method following methods are used so that all controllers work. * * voidIntegratedOrTokenizedTransaction : This method void integrated or Tokenized * transaction. Phone room controller has its * own implementation. Rest all use base class * implementation. * * isPaymentVoided : This method checks whether ipc payment is * voided. Regular controller has its own * implementation. Rest all use base class * implementation which return 'true'. * setCheckoutStatus : This method handles few components after * payment is removed. */ private void removePayment() { if (finalizeBaseDialog.sqfPaymentsTendered.getText().trim().length() > 0) { finalizeBaseDialog.sqfPaymentsTendered .dispatchEvent(pressEnterKey(finalizeBaseDialog)); } int selectedListIndex = finalizeBaseDialog.lstPaymentsTendered .getSelectedIndex(); if (selectedListIndex < 0) { return; } InvoicePaymentVO invPaymentVO = (InvoicePaymentVO) finalizeBaseDialog.lstPaymentsTendered .getSelectedValue(); if (invPaymentVO.getTenderTypeID().intValue() == RefTenderType.CASH) { finalizeBaseDialog.lblErrorMsg.setText(""); } Boolean ipcVoidPmtSuccess = null; if (invPaymentVO.getIntegratedPaymentType() != null && invPaymentVO.getIntegratedPaymentType().intValue() > 0) { // This is an integrated or tokenized transaction. We must void the // transaction before we can remove it // if the transaction amount is not zero. If the transaction amount // is zero, we didn't actually // call the service to perform the transaction before, so we'll skip // calling the void since we // don't actually have the required information to perform a void. if (invPaymentVO.getAmountApplied() .compareTo(BigDecimal.valueOf(0)) != 0) { int status = voidIntegratedOrTokenizedTransaction(invPaymentVO); if (status == DO_NOT_PROCEED) { return; } if (status == SUCCESS) { ipcVoidPmtSuccess = new Boolean(true); } else if (status == FAILED) { ipcVoidPmtSuccess = new Boolean(false); } } } boolean ipcPmt = invPaymentVO.getIntegratedPaymentType() != null && invPaymentVO.getIntegratedPaymentType().intValue() == 2; if (isPaymentVoided(ipcPmt, ipcVoidPmtSuccess)) { invoiceListModel.remove(selectedListIndex); finalizeBaseDialog.lstPaymentsTendered.clearSelection(); } else { logger.debug("Void failed. The payment remains in the listbox."); } setCheckoutStatus(); } /** * This method handles few components after payment is removed. To make all four * controllers to use this method following methods are used so that all * controllers work. * * handleExpressCheckout : This method handles Express Checkout button. * Phone room controller has empty implementation of * it. Rest all use base class implementation. * calculateAmountTendered : This method calculate amount tendered. Only * regular controller has its own implementation. * Rest all use base class implementation. * calculateAmountApplied : This method calculate amount applied. Only regular * controller has its own implementation. Rest all * use base class implementation. * isCustomerRequireToPayMore : This method checks if the amount applied is less * than the InvoiceTotal. Regular controller has its * own implementation. Rest all use base class * implementation. */ protected void setCheckoutStatus() { if (invoiceListModel.size() == 0) { finalizeBaseDialog.btnRemove.setEnabled(false); finalizeBaseDialog.btnPrint.setEnabled(false); // Don't enable the ExpCheckout and ReturnToInv buttons if we have // acquired an InvoiceNumber already if ((invoiceVO.getInvoiceNumber() != null) && (invoiceVO.getInvoiceNumber().intValue() >= 0)) { handleExpressCheckout(false); finalizeBaseDialog.btnReturnToInvoice.setEnabled(false); } else { handleExpressCheckout(true); finalizeBaseDialog.btnReturnToInvoice.setVisible(true); finalizeBaseDialog.btnReturnToInvoice.setEnabled(true); } checkFlagsAndSetButtons(); } bdAmtTendered = calculateAmountTendered(); finalizeBaseDialog.dlblTotalAmtTendered.setText(bdAmtTendered .toString()); computeAndDisplayBalanceDue(); BigDecimal amtApplied = calculateAmountApplied(); // if the amount applied is less than the InvoiceTotal, disable the // Print button if (isCustomerRequireToPayMore(amtApplied)) { finalizeBaseDialog.btnPrint.setEnabled(false); } enablePanel(); } /** * This method checks if the amount applied is less than the InvoiceTotal. * Optional controller has its own implementation. Rest all use base class * implementation. * @param amtApplied * @return */ protected boolean isCustomerRequireToPayMore(BigDecimal amtApplied){ return amtApplied.abs().compareTo(invoiceVO.getInvoiceTotal().abs()) < 0; } /** * This method handles Express Checkout button. Phone room controller * has empty implementation of it. Rest all use base class * implementation. * @param isEnable */ protected void handleExpressCheckout(boolean isEnable) { if (isEnable) { finalizeBaseDialog.btnExpressCheckout.setEnabled(InvoiceBL .allowExpressCheckout(isChargeInvoice())); } else { finalizeBaseDialog.btnExpressCheckout.setEnabled(false); } } /** * This method void integrated transaction.To make all three controllers to * use this method following methods are used so that all controllers work. * * getInvoicePaymentVO : This method returns InvoicePaymentVO. Non * phone room controller has its own * implementation. Rest all use base class * implementation. * @param invPaymentVO * @return */ protected boolean voidIntegratedTransaction(InvoicePaymentVO invPaymentVO) { // logger.debug("____________________: entering voidIntegratedTransaction(), invPaymentVO.getTenderTypeDesc() = " // + invPaymentVO.getTenderTypeDesc() ); IntegratedPaymentCardResponseDataDetail tranDtl = null; try { final IntegratedPaymentProcessHelper ipcFormHelper = new IntegratedPaymentProcessHelper(); tranDtl = ipcFormHelper.voidTransaction( invPaymentVO.getIpcJournalKey(), Profile.POINT_OF_SALE_CLIENT); if (tranDtl != null && tranDtl.getStatusCode() == IntegratedPaymentCardConstants.INVALID_VOID_REQUEST) { logger.warn("WARNING!!!Void request received for successful transaction. Payment Cannot be Removed. " + invPaymentVO.getIpcJournalKey() + " - $" + invPaymentVO.getAmountApplied().setScale(2) + " tranDtl: " + tranDtl); return false; } else if (tranDtl != null && tranDtl.getAuthorized() != null && !tranDtl.getAuthorized().booleanValue()) { String[] params = new String[] { "" + invPaymentVO.getAmountApplied().setScale(2) }; if (tranDtl.getResponseMessage() != null) { logger.debug("____________________ in voidIntegratedTransaction(), tranDtl.getResponseMessage() = " + tranDtl.getResponseMessage()); /** * Messages starting with 504 are TAMSII defined messages thrown from JBOSS5. */ if (tranDtl.getResponseMessage().startsWith("504")) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, tranDtl.getResponseMessage()); } else { logger.error("____________________ in voidIntegratedTransaction(), tranDtl.getResponseMessage():" + tranDtl.getResponseMessage() + " is not a VALID messageId ! "); if (invPaymentVO.getTenderTypeID().byteValue() == RefTenderType.NAPA_GIFT_CARD) { clientApplicationContext.getMessageMgr() .showMessage(finalizeBaseDialog, "5044a", params); } else { clientApplicationContext.getMessageMgr() .showMessage(finalizeBaseDialog, "5044c", params); } } } else { if (invPaymentVO.getTenderTypeID().byteValue() == RefTenderType.NAPA_GIFT_CARD) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "5044a", params); } else { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "5044c", params); } } String failedInfo = "Payment cannot be removed (void is not successful) Integrated payment: " + invPaymentVO.getIpcJournalKey() + " - $" + invPaymentVO.getAmountApplied().setScale(2); logger.warn(failedInfo); return false; } return true; } catch (ApplicationException e) { String failedInfo = "FAILED VOID: Integrated payment: " + invPaymentVO.getIpcJournalKey() + " - $" + invPaymentVO.getAmountApplied().setScale(2); logger.error(failedInfo, e); if (e.getUserMessageID() != null) { logger.debug("____________________ mm: in voidIntegratedTransaction(), e.getUserMessageID() = " + e.getUserMessageID()); clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, e.getUserMessageID()); } else { // 5049b = 2,N,card transaction of $1 was not voided. Click 'OK' // to resubmit or continue the invoice. logger.debug("____________________ mm: in voidIntegratedTransaction(), dispay 5049b "); String[] parms = new String[] { "" + invPaymentVO.getAmountApplied().setScale(2) }; clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "5049b", parms); } return false; } } /** * This method void tokenized transaction. * * @param invPaymentVO InvoicePaymentVO */ private void voidTokenizedTransaction(InvoicePaymentVO invPaymentVO) { try { ResponseDataDetail response = PaymentCardServiceFactory .getServiceInstance().voidTransaction( customerVO.getCustomerNumber(), invPaymentVO.getIntegratedToken(), invPaymentVO.getIntegratedTransactionRoutingId(), TsoConstant.FINALIZE_INOICE_DIALOG, getUserContext()); if (response == null || response.getResult() == null) { throw new ApplicationException( "The token transaction returned no results.", "151"); } else { // since the response came back, we need to check it for // approved, declined, etc. if ("ERROR".equalsIgnoreCase(response.getResult()) || "UNKNOWN".equalsIgnoreCase(response.getResult())) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "2275"); logger.error("Transaction Error or Unknown (TransRoutingId#):" + invPaymentVO.getIntegratedTransactionRoutingId() + "\n" + response.toString()); return; } else if (!"VOIDED".equalsIgnoreCase(response.getResult())) { throw new ApplicationException( "The token transaction returned an unknown response: " + "Transaction:\nToken:" + invPaymentVO.getIntegratedToken() + "TransactionRoutingId:" + invPaymentVO.getIntegratedTransactionRoutingId() + "\nResponse:" + response.toString(), "151"); } } } catch (ApplicationException applicationException) { logger.error(applicationException.toString(), applicationException); String msg = applicationException.getMessage(); if (msg != null && msg.lastIndexOf("}") > -1 && msg.length() > msg.lastIndexOf("}") + 1) { msg = msg.substring(msg.lastIndexOf("}") + 1); } clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, msg); return; } } /** * This method returns the user context id after login to tams-web. * * @return user context id * @throws ApplicationException */ private String getUserContext() throws ApplicationException { String userContextId = null; final ClientApplicationContext clientApplicationContext = ClientApplicationContext .getClientApplicationContext(); if (clientApplicationContext != null) { final TsoCurrentUser currentUser = clientApplicationContext .getCurrentUser(); final ServerInfoVO serverInfoVo = clientApplicationContext .getServerInfo(); if (currentUser != null && currentUser.getEmployeeNum() != null && serverInfoVo != null) { userContextId = SecurityServiceFactory.getServiceInstance() .loginToTamsWeb( currentUser.getEmployeeNum().intValue(), currentUser.getPassword(), serverInfoVo.getHost(), clientApplicationContext.getCurrentLocale() .getLanguage()); } } return userContextId; } /** * Problem: Multiple payments, with multiple instances of cash back. * The combination of the amount applied and the amount tendered is more than the balance due. * * But you could have a situation where the person is applying $5 against the invoice, and taking $100 cash back. * * So we have to be careful here. Your change due is a combination of: * * The difference between the amount tendered and the amount applied (cash back) * PLUS * the excess of the amount applied above and beyond the balance due. * * This is made trickier because the bdBalanceDue is a stateful variable that is the "variable of record" for how * much is owed - each time this method is called, we reduce the amount owed by a bit. * * Structure: * * // subtract the current applied amount. * bdBalanceDue = bdAmtApplied.subtract(bdBalanceDue).setScale(2, BigDecimal.ROUND_HALF_UP) * * // if bdBalanceDue is zero, or negative, we're done. Set changeDue == to * // amtTendered - amtApplied [cash back] + bdBalanceDue.negate() * * Problem - bdAmtApplied doesn't exist. * * Logically, it seems like we should be idempotent here. * * take the invoice total, subtract amout applied -> balance due * * If the result is positive, the customer still owes money * * if the result is zero, or negative, subtract (i.e. make it more negative) the difference between amt tendered and amt applied * * This properly handles all of the following cases: * * $50 invoice * * 1. Someone pays $55 in cash. bBalanceDue -> -5 * 2. Someone pays $50 with a debit card, and $25 cash back. bdBalanceDue -> -25 * 3. Someone pays $40 with a debit card, and $25 cash back. bdBalanceDue is still +10, and no cash back (yet). * When the person pays an additional $17 in cash, bdBalanceDue would be -33 * 4. Someone pays $35 with a debit card, and gets $25 cash back. bdBalanceDue is 15. * The person then pays $15 with a debit card, and gets $100 cash back. bdBalanceDue is -125 * * */ protected void computeAndDisplayBalanceDue() { logger.debug(": ENTER: computeAndDisplayBalanceDue()"); logger.debug(": invoiceTotal is: "+bdInvoiceTotal.toString()); // set up defaults. finalizeBaseDialog.dlblInvoiceTotal.setText( bdInvoiceTotal.toString() ); finalizeBaseDialog.dlblChangeDue.setText( "0.00" ); // if this is a return, the invoice total is negative, and there's no // change due. if (bdInvoiceTotal.compareTo(BD_ZERO) < 0) { // we don't need to calculate change due, the default of 0.00 is // correct. // we do need to calculate balance due. bdBalanceDue = bdAmtTendered.subtract(bdInvoiceTotal).setScale(2, BigDecimal.ROUND_HALF_UP); logger.debug(": (invoice < 0) balanceDue is: "+bdBalanceDue+", amt tendered is: "+bdAmtTendered); } else { BigDecimal amtApplied = calculateAmountApplied(); // a negative balance due means the customer owes us money, a positive one means // we owe them money. bdBalanceDue = amtApplied.subtract(bdInvoiceTotal).setScale( 2, BigDecimal.ROUND_HALF_UP ); logger.debug(": (invoice > 0) balanceDue is: "+bdBalanceDue+", amtApplied is: "+amtApplied); // if the balance due is zero or positive, we owe the customer money if (bdBalanceDue.compareTo(BD_ZERO) >= 0) { // cashback is amtTendered - amtApplied BigDecimal cashback = bdAmtTendered.subtract(amtApplied); logger.debug(": balance due is negative, cashback is: "+cashback); // if cashback is positive, add it to bdBalanceDue if (cashback.compareTo(BD_ZERO) == 1 ) { bdBalanceDue = bdBalanceDue.add(cashback); } logger.debug(": setting change due to balance due: "+bdBalanceDue); // and we can specify change due at this point. finalizeBaseDialog.dlblChangeDue.setText( bdBalanceDue.toString() ); } else { logger.debug(": balanceDue is negative: "+bdBalanceDue); // otherwise, they still owe money. // we don't have to do anything here. } } } /* * (non-Javadoc) * * @see * com.gpc.client.common.event.InvoiceListener#invoicePrinted(com.gpc.client * .common.event.InvoiceEvent) */ public void invoicePrinted(InvoiceEvent ie) { clearList(); resetAttAndPO(); resetValues(); resetPanel(); paymentController.refreshLists(); } /* * (non-Javadoc) * * @see * com.gpc.client.common.event.InvoiceListener#invoiceSaved(com.gpc.client * .common.event.InvoiceEvent) */ public void invoiceSaved(InvoiceEvent ie) { clearList(); resetAttAndPO(); resetValues(); resetPanel(); paymentController.refreshLists(); if (invoiceVO != null && invoiceVO.getLineItems()!=null) { logger.error("FinalizeInvoiceBaseController.invoiceSaved: for custID:" + invoiceVO.getCustomerID() + " /Number of line items:" + invoiceVO.getLineItems().size() + " /PONum:" + invoiceVO.getPONumber()+" /SessionId= "+invoiceVO.getSessionID()); } } /* (non-Javadoc) * @see java.awt.event.FocusListener#focusGained(java.awt.event.FocusEvent) * To make all four controllers to use this method following method is used so that * all controllers work. * * isOptionalDelivery : This method check whether optional delivery flag is * enabled. Current Optional controller implement this * method. Rest all use base controller method which * return 'false'. * focusSpecificGained : All the focus event which are specific to controller * are moved to this method. Regular and Optional * controller has empty implementation. Phone room and * Non Phone room Controller override this method to * their use. */ public void focusGained(FocusEvent fe) { if (fe.getComponent().getName() != null && fe.getComponent().getName() .equals(FinalizeBaseDialog.CB_PONUMBER)) { if (!isOptionalDelivery()) { if (InvoiceBL.isBlanketPOExpired(blanketPO)) { finalizeBaseDialog.lblErrorMsg.setText(strBlanketPOExpired); } else { if (finalizeBaseDialog != null && finalizeBaseDialog.cbPONumber != null && finalizeBaseDialog.cbPONumber.getEditor() != null && finalizeBaseDialog.cbPONumber.getEditor() .getEditorComponent() != null && invoiceVO != null) { if (!InvoiceBL.isPONumberValid( ((JTextField) finalizeBaseDialog.cbPONumber .getEditor().getEditorComponent()) .getText(), invoiceVO.getSubTotal(), customerVO)) { finalizeBaseDialog.lblErrorMsg .setText(strPORequired); } } } } else { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } else if (fe.getComponent().getName() != null && fe.getComponent().getName().equals("cbDelivery")) { if (finalizeBaseDialog.cbDelivery.getSelectedItem().equals( DELIVERY_EMPTY)) { finalizeBaseDialog.lblErrorMsg.setText(strDeliveryRequired); } } else if (fe.getComponent().getName() != null && fe.getComponent().getName().equals("fldDeliveryDate")) { finalizeBaseDialog.fldDeliveryTime .setVerifyInputWhenFocusTarget(false); setSpecificInputVerifier(false); finalizeBaseDialog.rbDeliveryPriority .setVerifyInputWhenFocusTarget(false); } else if (fe.getComponent().getName() != null && fe.getComponent().getName().equals("fldDeliveryTime")) { finalizeBaseDialog.fldDeliveryDate .setVerifyInputWhenFocusTarget(false); finalizeBaseDialog.rbDeliveryPriority .setVerifyInputWhenFocusTarget(false); setSpecificInputVerifier(false); } else if (fe.getComponent().getName() != null && fe.getComponent().getName().equals("rbDeliveryPriority")) { finalizeBaseDialog.fldDeliveryDate .setVerifyInputWhenFocusTarget(false); finalizeBaseDialog.fldDeliveryTime .setVerifyInputWhenFocusTarget(false); setSpecificInputVerifier(false); } else if (fe.getComponent().getName() != null && fe.getComponent().getName().equals("rbAM")) { finalizeBaseDialog.rbDeliveryPriority .setVerifyInputWhenFocusTarget(false); finalizeBaseDialog.fldDeliveryDate .setVerifyInputWhenFocusTarget(false); finalizeBaseDialog.fldDeliveryTime .setVerifyInputWhenFocusTarget(false); finalizeBaseDialog.rbPM.setVerifyInputWhenFocusTarget(false); } else if (fe.getComponent().getName() != null && fe.getComponent().getName().equals("rbPM")) { finalizeBaseDialog.rbDeliveryPriority .setVerifyInputWhenFocusTarget(false); finalizeBaseDialog.fldDeliveryDate .setVerifyInputWhenFocusTarget(false); finalizeBaseDialog.fldDeliveryTime .setVerifyInputWhenFocusTarget(false); finalizeBaseDialog.rbAM.setVerifyInputWhenFocusTarget(false); } else if (fe.getComponent().getName() != null && fe.getComponent().getName().equals("rbDeliveryYes")) { finalizeBaseDialog.rbDeliveryNo .setVerifyInputWhenFocusTarget(false); } else if (fe.getComponent().getName() != null && fe.getComponent().getName().equals("rbDeliveryNo")) { finalizeBaseDialog.rbDeliveryYes .setVerifyInputWhenFocusTarget(false); } else if (fe.getComponent().getName() != null && fe.getComponent().getName().equals("fldMiscAdjustments")) { if (isOptionalDelivery()) { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } else if (fe.getComponent().getName() != null && fe.getComponent().getName().equals("lstPaymentMethod")) { if (isOptionalDelivery()) { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } else if (fe.getComponent().getName() != null && fe.getComponent().getName().equals("cbTax1")) { if (isOptionalDelivery()) { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } else if (fe.getComponent().getName() != null && fe.getComponent().getName().equals("fldTax1")) { if (isOptionalDelivery()) { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } else if (fe.getComponent().getName() != null && fe.getComponent().getName().equals("fldTax2")) { if (isOptionalDelivery()) { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } else if (fe.getComponent().getName() != null && fe.getComponent().getName().equals("cbPrinter")) { if (isOptionalDelivery()) { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } else if (fe.getComponent().getName() != null && fe.getComponent().getName().equals("sqfPaymentMethod")) { if (isOptionalDelivery()) { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } else if (fe.getComponent().getName() != null && fe.getComponent().getName().equals("btnErase")) { if (isOptionalDelivery()) { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } else if (fe.getComponent().getName() != null && fe.getComponent().getName().equals("btnPrint")) { if (isOptionalDelivery()) { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } else if (fe.getComponent().getName() != null && fe.getComponent().getName().equals("btnSaveInvoice")) { if (isOptionalDelivery()) { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } else if (fe.getComponent().getName() != null && fe.getComponent().getName().equals("btnExpressCheckout")) { if (isOptionalDelivery()) { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } else if (fe.getComponent().getName() != null && fe.getComponent().getName().equals("fldAttention")) { if (isOptionalDelivery()) { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } focusSpecificGained(fe); } /* * (non-Javadoc) * * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent) */ public void keyPressed(KeyEvent ke) { if (ke.getModifiers() == 0 && ke.getKeyCode() == 27) { escapeKeyPressed = false; } } /* (non-Javadoc) * @see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent) * To make all four controllers to use this method following method is used so that * all controllers work. * keySpecificRelead : All the key event which are not same in all four controller * are moved to this method. Again Optional controller and Phone room Controller * override this method to their use. */ public void keyReleased(KeyEvent ke) { Component glassPane = finalizeBaseDialog.getGlassPane(); if (glassPane.isVisible()) { Toolkit.getDefaultToolkit().beep(); ke.consume(); return; } if (ke.getModifiers() == 0) { switch (ke.getKeyCode()) { case KeyEvent.VK_DOWN: if (ke.getSource() instanceof JComboBox && !((JComboBox) ke.getSource()).isPopupVisible()) { JComboBox source = (JComboBox) ke.getSource(); source.setPopupVisible(true); } break; case KeyEvent.VK_F2: if (finalizeBaseDialog.btnPrint.isEnabled()) { if (!isOptionalDelivery()) { finalizeBaseDialog.btnPrint.doClick(); } else { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } break; case KeyEvent.VK_F9: if (finalizeBaseDialog.btnRemove.isEnabled()) { finalizeBaseDialog.btnRemove.doClick(); } break; case KeyEvent.VK_F11: if (finalizeBaseDialog.rbDeliveryPriority.isEnabled()) { if (!isOptionalDelivery()) { finalizeBaseDialog.rbDeliveryPriority.grabFocus(); finalizeBaseDialog.rbDeliveryPriority.doClick(); } else { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } break; case KeyEvent.VK_F12: if (finalizeBaseDialog.rbDeliveryTime.isEnabled()) { if (!isOptionalDelivery()) { finalizeBaseDialog.rbDeliveryTime.grabFocus(); finalizeBaseDialog.rbDeliveryTime.doClick(); } else { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } break; case KeyEvent.VK_ESCAPE: if (!escapeKeyPressed && finalizeBaseDialog.btnReturnToInvoice.isEnabled()) { finalizeBaseDialog.btnReturnToInvoice.doClick(); } else { escapeKeyPressed = false; paymentController.keyReleased(ke); } break; case KeyEvent.VK_F5: case KeyEvent.VK_F6: case KeyEvent.VK_F8: case KeyEvent.VK_F10: case KeyEvent.VK_RIGHT: case KeyEvent.VK_LEFT: case KeyEvent.VK_N: case KeyEvent.VK_Y: keySpecificReleased(ke); break; default: paymentController.keyReleased(ke); break; } } } /* * (non-Javadoc) * * @see com.gpc.client.pointofsale.util.BaseController#getModel() */ public PointOfSaleVO getModel() { return this.invoiceVO; } /* * (non-Javadoc) * * @see com.gpc.client.pointofsale.util.BaseController#getView() */ public IView getView() { return this.finalizeBaseDialog; } /* * (non-Javadoc) * * @see * com.gpc.client.pointofsale.util.BaseController#installViewListeners() * To make all four controllers to use this method following method is used so * that all controllers work. * * installSpecificViewListeners : This method install listeners for components * which are not common across controller. */ public void installViewListeners() { finalizeBaseDialog.btnPrint.addActionListener(this); finalizeBaseDialog.btnSaveInvoice.addActionListener(this); finalizeBaseDialog.btnSaveInvoice.addKeyListener(this); finalizeBaseDialog.cbPrinter.addKeyListener(this); finalizeBaseDialog.btnReturnToInvoice.addActionListener(this); finalizeBaseDialog.btnRemove.addActionListener(this); finalizeBaseDialog.cbDeliveryPriority.addActionListener(this); finalizeBaseDialog.cbDeliveryPriority.addKeyListener(this); finalizeBaseDialog.btnPrint.addKeyListener(this); finalizeBaseDialog.btnReturnToInvoice.addKeyListener(this); finalizeBaseDialog.btnRemove.addKeyListener(this); finalizeBaseDialog.rbDeliveryPriority.addActionListener(this); finalizeBaseDialog.rbDeliveryTime.addActionListener(this); finalizeBaseDialog.fldDeliveryCharge.addFocusListener(this); finalizeBaseDialog.fldAttention.addFocusListener(this); finalizeBaseDialog.cbTax1.addActionListener(this); finalizeBaseDialog.cbTax1.addKeyListener(this); finalizeBaseDialog.addKeyListener(this); finalizeBaseDialog.cbPONumber.addFocusListener(this); finalizeBaseDialog.cbPONumber.getEditor().getEditorComponent() .addFocusListener(this); finalizeBaseDialog.cbPONumber.getEditor().getEditorComponent().addKeyListener(this); finalizeBaseDialog.addWindowListener(this); finalizeBaseDialog.lstPaymentMethod.addMouseListener(this); finalizeBaseDialog.sqfPaymentMethod.addKeyListener(this); finalizeBaseDialog.fldAttention.addKeyListener(this); finalizeBaseDialog.cbPONumber.addKeyListener(this); finalizeBaseDialog.sqfPaymentsTendered.addKeyListener(this); finalizeBaseDialog.fldDeliveryCharge.addKeyListener(this); finalizeBaseDialog.fldDeliveryDate.addKeyListener(this); finalizeBaseDialog.fldDeliveryMethod.addKeyListener(this); finalizeBaseDialog.fldDeliveryTime.addKeyListener(this); finalizeBaseDialog.fldMiscAdjustments.addKeyListener(this); finalizeBaseDialog.fldTax1.addKeyListener(this); finalizeBaseDialog.fldTax2.addKeyListener(this); if (RefStoreConfigurationUtil.isRefundTenderRestrictionEnabled()) { finalizeBaseDialog.btnMgrOverride.addActionListener(this); finalizeBaseDialog.btnMgrOverride.addKeyListener(this); } installSpecificViewListeners(); } /** * This method install listeners for components * which are not common across controller. */ protected void installSpecificViewListeners() { finalizeBaseDialog.btnVoid.addActionListener(this); finalizeBaseDialog.btnExpressCheckout.addActionListener(this); finalizeBaseDialog.btnErase.addActionListener(this); finalizeBaseDialog.btnVoid.addKeyListener(this); finalizeBaseDialog.btnExpressCheckout.addKeyListener(this); finalizeBaseDialog.btnErase.addKeyListener(this); } /* * (non-Javadoc) * * @see * com.gpc.client.pointofsale.util.BaseController#installBusinessListeners() */ public void installBusinessListeners() { // Whatever the listener added here should be removed inside // removeBusinessListeners method. // This should be done to make avail of new listeners (related to phone // room) // in case of phone room invoicing. pointOfSaleEventDispatcher.addListener(InvoiceListener.class, this); pointOfSaleEventDispatcher.addListener(PaymentListener.class, this); pointOfSaleEventDispatcher.addListener(CustomerListener.class, this); } /** * Removes the business listeners, which ever added to * 'pointOfSaleEventDispatcher' inside 'installBusinessListeners' method */ public void removeBusinessListeners() { pointOfSaleEventDispatcher.removeListener(InvoiceListener.class, this); pointOfSaleEventDispatcher.removeListener(PaymentListener.class, this); pointOfSaleEventDispatcher.removeListener(CustomerListener.class, this); } /* * (non-Javadoc) * * @see com.gpc.client.pointofsale.util.BaseController#installVerifiers() * To make all four controllers to use this method following method is * used so that all controllers work. * * installSpecificVerifiers : This method install verifiers for * components which are not common across * controller. */ public void installVerifiers() { FwoBaseInputVerifier baseVerifier = new FwoBaseInputVerifier(this); baseVerifier.setAdditionalValidationOnClient(true); // set up the date verifier for the Delivery Date field. FwoDateVerifier dateVerifier = new FwoDateVerifier(this); dateVerifier.setAdditionalValidationOnClient(true); Profile profile = ClientApplicationContext .getClientApplicationContext().getProfile( Profile.POINT_OF_SALE_CLIENT, ClientApplicationContext.getClientApplicationContext() .getLocation()); finalizeBaseDialog.fldDeliveryDate .setDocument(new TsoTextPersistedDateDocument( finalizeBaseDialog.fldDeliveryDate, profile .getStoreProfile().getRefDateFormatId() .intValue())); finalizeBaseDialog.fldDeliveryDate.setInputVerifier(dateVerifier); // set up the date verifier for the Delivery Time field. TsoSimpleTimeVerifier timeVerifier = new TsoSimpleTimeVerifier(this); timeVerifier.setAdditionalValidationOnClient(true); finalizeBaseDialog.fldDeliveryTime.setDocument(new TimeTextDocument()); finalizeBaseDialog.fldDeliveryTime.setInputVerifier(timeVerifier); installSpecificVerifiers(baseVerifier); finalizeBaseDialog.fldDeliveryCharge.setInputVerifier(baseVerifier); // add Decimal Number document to delivery charge FwoValidatedDecimalNumberDocument fvdnd = new FwoValidatedDecimalNumberDocument( finalizeBaseDialog.fldDeliveryCharge); String validInputChars = String.valueOf(fvdnd.getPattern() .getValidInputChars()) + "@"; fvdnd.setValidInputChars(validInputChars.toCharArray()); finalizeBaseDialog.fldDeliveryCharge.setDocument(fvdnd); finalizeBaseDialog.fldDeliveryMethod.setInputVerifier(baseVerifier); JTextField fld = (JTextField) finalizeBaseDialog.cbPONumber.getEditor() .getEditorComponent(); fld.setDocument(new DefaultDocument(fld, clientApplicationContext .getSystemDAO().getPONumberCharLength().intValue(), DefaultDocument.ALPHANUMERIC, new char[] { ',', '.', '-', ' ', '#', '/', '_' })); finalizeBaseDialog.cbPONumber.setInputVerifier(baseVerifier); fld.setInputVerifier(baseVerifier); FwoValidatedWholeNumberDocument vwnd = new FwoValidatedWholeNumberDocument( finalizeBaseDialog.fldMiscAdjustments); vwnd.setUseSeparators(false); validInputChars = String .valueOf(vwnd.getPattern().getValidInputChars()) + "@"; vwnd.setValidInputChars(validInputChars.toCharArray()); finalizeBaseDialog.fldMiscAdjustments.setDocument(vwnd); finalizeBaseDialog.fldMiscAdjustments.setInputVerifier(baseVerifier); finalizeBaseDialog.cbTax1.setInputVerifier(baseVerifier); finalizeBaseDialog.fldTax1 .setDocument(new FwoValidatedDecimalNumberDocument( finalizeBaseDialog.fldTax1)); finalizeBaseDialog.fldTax1.setInputVerifier(baseVerifier); finalizeBaseDialog.fldTax2 .setDocument(new FwoValidatedDecimalNumberDocument( finalizeBaseDialog.fldTax2)); finalizeBaseDialog.fldTax2.setInputVerifier(baseVerifier); finalizeBaseDialog.sqfPaymentMethod.setInputVerifier(baseVerifier); finalizeBaseDialog.sqfPaymentsTendered.setInputVerifier(baseVerifier); } /** * This method verify if input param s is number or not * @param s * @return false if s is a number, else true (meaning it is a number) */ private boolean isNaN(String s) { if (s == null) { return true; } BigDecimal bd = null; try { bd = new BigDecimal(s); } catch (NumberFormatException e) { logger.info(e); return true; } return false; } /* * (non-Javadoc) * * @see * com.gpc.client.pointofsale.util.BaseController#validateComponent(javax * .swing.JComponent) */ public boolean validateComponent(JComponent currentComponent) { boolean retFlag = true; if (currentComponent.getName() == null) { return retFlag; } if (currentComponent.getName().equals("fldDeliveryCharge")) { retFlag = checkDeliveryCharge(); } else if (currentComponent.getName().equals("fldDeliveryDate") || currentComponent.getName().equals("fldDeliveryTime") || currentComponent.getName().equals("rbAM") || currentComponent.getName().equals("rbPM")) { retFlag = (validateDeliveryDate() && validateDeliveryTime()); if (retFlag == false && (currentComponent.getName().equals("rbAM") || currentComponent .getName().equals("rbPM"))) { finalizeBaseDialog.fldDeliveryTime.requestFocus(); finalizeBaseDialog.fldDeliveryTime.selectAll(); } } else if (currentComponent.getName().equals("fldAttention")) { if (validateAttention()) { finalizeBaseDialog.lblErrorMsg.setText(""); retFlag = true; } else { finalizeBaseDialog.lblErrorMsg.setText(strAttentionRequired); retFlag = false; } } else if (currentComponent.getName().equals( FinalizeBaseDialog.CB_PONUMBER)) { if (InvoiceBL.isPONumberValid( ((JTextField) finalizeBaseDialog.cbPONumber.getEditor() .getEditorComponent()).getText(), invoiceVO .getSubTotal(), customerVO)) { finalizeBaseDialog.lblErrorMsg.setText(""); retFlag = true; } else { if (InvoiceBL.isBlanketPOExpired(blanketPO)) { finalizeBaseDialog.lblErrorMsg.setText(strBlanketPOExpired); } else { finalizeBaseDialog.lblErrorMsg.setText(strPORequired); } retFlag = false; } } else if (currentComponent.getName().equals("cbDelivery")) { if (finalizeBaseDialog.cbDelivery.getSelectedItem().equals( DELIVERY_EMPTY)) { finalizeBaseDialog.lblErrorMsg.setText(strDeliveryRequired); retFlag = false; } else { finalizeBaseDialog.lblErrorMsg .setText(returnEmptyStringIfMatched( finalizeBaseDialog.lblErrorMsg.getText(), strDeliveryRequired)); retFlag = true; } } else if (currentComponent.getName().equals("fldMiscAdjustments")) { String s = ((JTextField) currentComponent).getText(); if ((s == null) || (s.trim().equals(""))) { return false; } else if (s.startsWith("@")) { finalizeBaseDialog.fldMiscAdjustments.setText(""); return false; } else if (isNaN(s)) { String[] parms = new String[] { (s != null ? s : "") }; ClientApplicationContext.getClientApplicationContext() .getMessageMgr() .showMessage(finalizeBaseDialog, "176", parms); return false; } calculateMiscAdjustments(); calculateInvoiceTotal(); retFlag = true; } else if (currentComponent.getName().equals("sqfPaymentMethod")) { String s = finalizeBaseDialog.sqfPaymentMethod.getText().trim(); if (s.equals("")) { retFlag = true; } else { finalizeBaseDialog.sqfPaymentMethod.selectListItems(); Object oSelected = finalizeBaseDialog.lstPaymentMethod .getSelectedValue(); if (oSelected == null) { retFlag = false; } else { IDValuePairVO item = (IDValuePairVO) oSelected; retFlag = isValidPaymentMethod((Short) item.getID()); } if (!retFlag) { logger.debug("validateComponent: clear paymentMethod list-field"); finalizeBaseDialog.lstPaymentMethod.clearSelection(); finalizeBaseDialog.sqfPaymentMethod.setText(""); } } } else if (currentComponent.getName().equals("sqfPaymentsTendered")) { String s = finalizeBaseDialog.sqfPaymentsTendered.getText().trim(); if (s.equals("")) { retFlag = true; } else { finalizeBaseDialog.sqfPaymentsTendered.selectListItems(); } } else if (currentComponent.getName().equals("cbTax1")) { retFlag = true; } else if (currentComponent.getName().equals("fldTax1")) { if ((finalizeBaseDialog.fldTax1.getText() != null) && (!finalizeBaseDialog.fldTax1.getText().equals(""))) { logger.debug("**** validateComponent, calling processFldTax1"); processFldTax1(); retFlag = true; } else { retFlag = false; } } else if (currentComponent.getName().equals("fldTax2")) { processFldTax2(); retFlag = true; } return retFlag; } /** * This method calculates MISC adjustments */ protected void calculateMiscAdjustments() { String s = finalizeBaseDialog.fldMiscAdjustments.getText(); if ((s == null) || (s.trim().equals(""))) { s = "0"; finalizeBaseDialog.fldMiscAdjustments.setText(s); } BigDecimal bdTempMiscAdjust = new BigDecimal(s); BigDecimal bdMiscAdjustment = bdTempMiscAdjust.setScale(2, BigDecimal.ROUND_HALF_UP); calculateMiscAdjust(bdMiscAdjustment); } /** * This method validate invoice payment.To make all four controllers to use this * method following method is used so that all controllers work. * * isInvoicePaidInFull : This method checks whether invoice is paid fully. * Current Regular controller has specific implementation. * Rest all use base class implementation. * isCustomerAllowedToUseChargeOnAccountToBuyA_NAPA_GiftCard : * This method checks whether a charge tender type is used * to transact napa gift card. Current Regular controller * has specific implementation. Rest all use base class * implementation. * @param id * @return true if validated successfully. */ private boolean isValidPaymentMethod(Short id) { logger.debug("Inside isValidPaymentMethod"); if (id == null) { return false; } if (id.intValue() == 0) { return true; } if (isInvoicePaidInFull()) { // 1284 = Invoice is paid in full, cannot accept more payments.s clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "1284"); logger.debug("-- isValidPaymentMethod: clear paymentMethod list field."); finalizeBaseDialog.lstPaymentMethod.clearSelection(); finalizeBaseDialog.sqfPaymentMethod.setText(""); return false; } if ((invoiceListModel.getData() != null) && (invoiceListModel.getData().size() > 0)) { InvoicePaymentVO vo = (InvoicePaymentVO) invoiceListModel.getData() .elementAt(0); if ((vo.getTenderTypeID() != null) && (vo.getTenderTypeID().intValue() == RefTenderType.CHARGE_ON_ACCOUNT)) { finalizeBaseDialog.lstPaymentMethod.clearSelection(); finalizeBaseDialog.sqfPaymentMethod.setText(""); // #1282, Cannot choose Charge On Account payment method with // Other Payments. clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "1282"); return false; } } if (id.intValue() == RefTenderTypeCategory.GIFT_CERTIFICATE || id.intValue() == RefTenderTypeCategory.COUPON || id.intValue() == RefTenderTypeCategory.NAPA_GIFT_CARD) { return true; } if (id.intValue() == RefTenderTypeCategory.CHECK && !finalizeHandler.isCheckConfiguredProperly()) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "1295"); return false; } boolean retValue = true; switch (id.intValue()) { case RefTenderTypeCategory.CREDIT_CARD: case RefTenderTypeCategory.CHECK: retValue = isPaymentMethodAlreadyEntered(id.intValue(), invoiceListModel.getData()); break; case RefTenderTypeCategory.INTEGRATED_PAYMENT: retValue = true; break; } return retValue; } /** * This method checks whether invoice is paid fully. Current Optional * controller has specific implementation. Rest all use base class * implementation. * * @return true if invoice paid in full */ protected boolean isInvoicePaidInFull() { boolean invoicePaidInFull = false; /* * TII-18210/TII-18320 * 'if' condition added to fix the 'Print [F2]' button issue. Root * cause for the issue is AMOUNT_APPLIED value does not get updated * in few scenarios. Change TII-18482 is created for it. When root * cause is fixed in future releases, this 'if' clause can be removed. */ if (customerVO != null && customerVO.getBillTypeCode().equals( RefBillingType.CHARGE_ONLY) && !CustomerBL.isNapaOnlineCustomer(customerVO)) { invoicePaidInFull = !invoiceFinalized && (invoiceListModel.getData() != null) && (invoiceListModel.getData().size() > 0) && Math.abs(bdAmtTendered.doubleValue()) >= Math.abs(bdInvoiceTotal.doubleValue()); } else { invoicePaidInFull = !invoiceFinalized && invoiceListModel.getData() != null && invoiceListModel.getData().size() > 0 && Math.abs(calculateAmountApplied().doubleValue()) >= Math.abs(bdInvoiceTotal.doubleValue()); } return invoicePaidInFull; } /** * This method checks if payment method already entered. * * @param paymentMethodID * @param vCurrentPayments * @return */ private boolean isPaymentMethodAlreadyEntered(int paymentMethodID, Vector vCurrentPayments) { logger.debug("Inside isPaymentMethodAlreadyEntered"); if ((vCurrentPayments == null) || (vCurrentPayments.size() == 0)) { return true; } int numOfCurrentPayments = vCurrentPayments.size(); boolean retValue = true; Object o = null; for (int i = 0; i < numOfCurrentPayments; i++) { o = vCurrentPayments.elementAt(i); if (!(o instanceof InvoicePaymentVO)) { continue; } InvoicePaymentVO pVO = (InvoicePaymentVO) o; if (pVO.getTenderTypeID() == null) { continue; } logger.info("pVO.getTenderTypeID().intValue() = " + pVO.getTenderTypeID().intValue() + " paymentMethodID = " + paymentMethodID); if (pVO.getTenderTypeID().intValue() == RefTenderType.CHECK && paymentMethodID == RefTenderTypeCategory.CHECK) { logger.debug("Cannot add more than one Check Payment Method"); clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "1292"); retValue = false; } if (retValue) { logger.info("Payment Method is invalid"); break; } } logger.debug("getting out of isPaymentMethodAlreadyEntered"); return retValue; } /* * (non-Javadoc) * * @see * com.gpc.client.pointofsale.util.BaseController#installFocusDeciders() * To make all four controllers to use this method following method is * used so that all controllers work. * * installSpecificFocusDeciders : This method install listeners for components * which are not common across controller. */ public void installFocusDeciders() { finalizeBaseDialog.fldDeliveryCharge.putClientProperty( FocusDecider.NAME, this); finalizeBaseDialog.cbDeliveryPriority.putClientProperty( FocusDecider.NAME, this); finalizeBaseDialog.fldDeliveryTime.putClientProperty(FocusDecider.NAME, this); finalizeBaseDialog.fldDeliveryDate.putClientProperty(FocusDecider.NAME, this); finalizeBaseDialog.rbDeliveryTime.putClientProperty(FocusDecider.NAME, this); finalizeBaseDialog.fldDeliveryMethod.putClientProperty( FocusDecider.NAME, this); finalizeBaseDialog.fldAttention.putClientProperty(FocusDecider.NAME, this); finalizeBaseDialog.cbPONumber .putClientProperty(FocusDecider.NAME, this); finalizeBaseDialog.fldMiscAdjustments.putClientProperty( FocusDecider.NAME, this); finalizeBaseDialog.sqfPaymentsTendered.putClientProperty( FocusDecider.NAME, this); finalizeBaseDialog.cbTax1.putClientProperty(FocusDecider.NAME, this); finalizeBaseDialog.sqfPaymentMethod.putClientProperty( FocusDecider.NAME, this); finalizeBaseDialog.fldTax1.putClientProperty(FocusDecider.NAME, this); finalizeBaseDialog.cbPrinter.putClientProperty(FocusDecider.NAME, this); finalizeBaseDialog.fldDeliveryDate.addFocusListener(this); finalizeBaseDialog.fldDeliveryTime.addFocusListener(this); finalizeBaseDialog.rbDeliveryPriority.addFocusListener(this); installSpecificFocusDeciders(); } /* * (non-Javadoc) * * @see com.gpc.client.common.focusmanager.FocusDecider# * getFocusableComponentAfterVerification(javax.swing.JComponent, boolean) * * To make all four controllers to use this method following method is used so that * all controllers work. * getSpecificFocusableComponentAfterVerification : Components which are having * different implementation is implementing this method to their use. */ public JComponent getFocusableComponentAfterVerification( JComponent currentComponent, boolean tranferFocusForward) { String componentName = currentComponent.getName(); JComponent returnComponent = null; if (componentName == null) { return null; } if (componentName.equals("sqfPaymentMethod")) { if (tranferFocusForward) { Object oSelected = finalizeBaseDialog.lstPaymentMethod .getSelectedValue(); IDValuePairVO item = (IDValuePairVO) oSelected; if ((item != null) && (item.getID() != null)) { logger.debug("=====>> call selectPaymentMethod: REF_TENDER_TYPE_CATEGORY.ID: item.getID() = " + item.getID()); selectPaymentMethod(((Short) item.getID()).intValue()); } } else { finalizeBaseDialog.lstPaymentMethod.clearSelection(); finalizeBaseDialog.sqfPaymentMethod.setText(""); } } else if (componentName.equals("btnRemove")) { if (finalizeBaseDialog.lstPaymentsTendered.getModel().getSize() <= 0) { returnComponent = finalizeBaseDialog.sqfPaymentMethod; } else { returnComponent = finalizeBaseDialog.sqfPaymentsTendered; } } else if (componentName.equals("fldTax1")) { if (tranferFocusForward) { if (invoiceVO.getManualTransaction().booleanValue()) { String s = finalizeBaseDialog.fldTax1.getText(); if (s == null || s.equals("")) { returnComponent = finalizeBaseDialog.fldTax1; } else { returnComponent = finalizeBaseDialog.sqfPaymentMethod; } } } else { returnComponent = finalizeBaseDialog.fldMiscAdjustments; } } else { returnComponent = getSpecificFocusableComponentAfterVerification( componentName, tranferFocusForward); } return returnComponent; } /** * This method clears global values. To make all four controllers to use * this method following method is used so that all controllers work. * * resetSpecificValues : This method loads default printer id. All * controller except phone room use base class * method. Phone room controller has empty * implementation. */ private void resetValues() { bdInvoiceSubtotal = BD_ZERO; bdInvoiceTotal = BD_ZERO; bdAmtTendered = BD_ZERO; bdBalanceDue = BD_ZERO; deliveryFlag = "O"; skipMiscAdj = true; skipTax = true; skipPaymentMethod = false; invoiceListModel.getData().clear(); paymentController.displayPaymentPanel(DEFAULTPANEL); terminalVO = clientApplicationContext.getSystemDAO() .getTerminalFromIPAddress( clientApplicationContext.getClientIPAddress(), new Integer(clientApplicationContext.getLocation())); resetSpecificValues(); loyaltyCustomerExternalIdentifier = null; refLoyaltyCustomerStatusId = null; loyaltyInvoiceExternalIdentifier = null; returnHistory = null; } /** * This method loads default printer id. All controller except phone * room use base class method. Phone room controller has empty * implementation. */ protected void resetSpecificValues() { defaultPrinterID = -1; if (customerVO != null && ((customerVO.getBillTypeCode() == null) || (customerVO.getBillTypeCode() .equalsIgnoreCase(RefBillingType.CASH_ONLY)) || (customerVO .getBillTypeCode() .equalsIgnoreCase(RefBillingType.CASH_OR_CHARGE)))) { defaultPrinterID = terminalVO.getCashInvoicePrinterID(); } else { defaultPrinterID = terminalVO.getChargeInvoicePrinterID(); } } /** * This method work on delivery panel. To make all four controllers * to use this method following methods are used so that all controllers work. * reSelectAMPM : The implementation of this method select or deselect AM PM * radio button. Current Regular and Optional checkout * controller has implementation. Rest has empty implementation. * reSelectAMPM : The implementation of this method enable or disable AM PM * radio button. Current Regular and Optional checkout * controller has implementation. Rest has empty implementation. */ public void resetDelivery() { finalizeBaseDialog.cbDeliveryPriority.setSelectedIndex(0); finalizeBaseDialog.rbDeliveryPriority.setSelected(true); finalizeBaseDialog.rbDeliveryTime.setSelected(false); finalizeBaseDialog.rbDeliveryPriority.setEnabled(false); finalizeBaseDialog.rbDeliveryTime.setEnabled(false); finalizeBaseDialog.lblDeliveryCharge.setEnabled(false); finalizeBaseDialog.lblDeliveryPriority.setEnabled(false); finalizeBaseDialog.lblDeliveryTime.setEnabled(false); finalizeBaseDialog.lblDeliveryMethod.setEnabled(false); finalizeBaseDialog.lblDeliveryDate.setEnabled(false); finalizeBaseDialog.cbDeliveryPriority.setEnabled(false); finalizeBaseDialog.fldDeliveryCharge.setEnabled(false); finalizeBaseDialog.fldDeliveryMethod.setEnabled(false); finalizeBaseDialog.fldDeliveryMethod.setText(""); finalizeBaseDialog.fldDeliveryTime.setEnabled(false); finalizeBaseDialog.fldDeliveryTime.setText(""); resetAMPM(false); reSelectAMPM(); finalizeBaseDialog.fldDeliveryDate.setEnabled(false); finalizeBaseDialog.fldDeliveryDate.setText(""); finalizeBaseDialog.fldDeliveryCharge.setText("0.00"); finalizeBaseDialog.dlblDeliveryCharge.setText("0.00"); invoiceVO.setDeliveryCharge(BD_ZERO); invoiceVO.setDeliveryChargeTaxable1(Boolean.FALSE); invoiceVO.setDeliveryChargeTaxable2(Boolean.FALSE); } /** * This method work on delivery panel. To make all four controllers * to use this method following methods are used so that all controllers work. * reSelectAMPM : The implementation of this method select or deselect AM PM * radio button. Current Regular and Optional checkout * controller has implementation. Rest has empty implementation. * reSelectAMPM : The implementation of this method enable or disable AM PM * radio button. Current Regular and Optional checkout * controller has implementation. Rest has empty implementation. */ public void checkDeliveryState() { boolean deliveryEnabled = isDeliveryChecked(); finalizeBaseDialog.lblDeliveryCharge.setEnabled(deliveryEnabled); finalizeBaseDialog.fldDeliveryCharge.setEnabled(deliveryEnabled); finalizeBaseDialog.rbDeliveryPriority.setEnabled(deliveryEnabled); finalizeBaseDialog.rbDeliveryTime.setEnabled(deliveryEnabled); finalizeBaseDialog.lblDeliveryPriority.setEnabled(deliveryEnabled); finalizeBaseDialog.cbDeliveryPriority.setEnabled(deliveryEnabled); finalizeBaseDialog.lblDeliveryTime.setEnabled(deliveryEnabled); finalizeBaseDialog.fldDeliveryTime.setEnabled(deliveryEnabled); resetAMPM(useAmPmRadios && deliveryEnabled); finalizeBaseDialog.lblDeliveryDate.setEnabled(deliveryEnabled); finalizeBaseDialog.fldDeliveryDate.setEnabled(deliveryEnabled); finalizeBaseDialog.lblDeliveryMethod.setEnabled(deliveryEnabled); finalizeBaseDialog.fldDeliveryMethod.setEnabled(deliveryEnabled); finalizeBaseDialog.rbDeliveryPriority.setSelected(true); if (deliveryEnabled) { finalizeBaseDialog.fldDeliveryMethod.setText(strDeliveryMethod); defaultDelivery = finalizeBaseDialog.fldDeliveryMethod.getText(); if (finalizeBaseDialog.rbDeliveryPriority.isSelected()) { finalizeBaseDialog.lblDeliveryTime.setEnabled(false); finalizeBaseDialog.fldDeliveryTime.setEnabled(false); resetAMPM(false); finalizeBaseDialog.lblDeliveryDate.setEnabled(false); finalizeBaseDialog.fldDeliveryDate.setEnabled(false); } else { finalizeBaseDialog.lblDeliveryPriority.setEnabled(false); finalizeBaseDialog.cbDeliveryPriority.setEnabled(false); } } finalizeBaseDialog.fldDeliveryTime.setText(""); finalizeBaseDialog.fldDeliveryDate.setText(""); reSelectAMPM(); } /** * This method work on delivery panel. To make all four controllers * to use this method following methods are used so that all controllers work. * reSelectAMPM : The implementation of this method select or deselect AM PM * radio button. Current Regular and Optional checkout * controller has implementation. Rest has empty implementation. * reSelectAMPM : The implementation of this method enable or disable AM PM * radio button. Current Regular and Optional checkout * controller has implementation. Rest has empty implementation. * @param setPriority true is priority is selected. */ public void setDeliveryOption(boolean setPriority) { int priorityID = 0; if (setPriority) { if (customerDeliveryVO != null && customerDeliveryVO.getDeliveryPriorityID() != null) { priorityID = customerDeliveryVO.getDeliveryPriorityID() .intValue(); enableDelivery(priorityID); } else { finalizeBaseDialog.cbDeliveryPriority.setSelectedIndex(0); // not // assigned } finalizeBaseDialog.fldDeliveryTime.setText(""); finalizeBaseDialog.fldDeliveryDate.setText(""); reSelectAMPM(); } else { finalizeBaseDialog.cbDeliveryPriority.setSelectedIndex(0); try { FwoPattern datePattern = FwoPattern.getDatePatternInstance( clientApplicationContext.getCurrentLocale(), new Integer(clientApplicationContext .getProfile(Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()) .getStoreProfile().getRefDateFormatId() .intValue())); finalizeBaseDialog.fldDeliveryDate.setText(datePattern .format(new Date())); } catch (PatternFormatException pfe) { logger.error(pfe.toString(), pfe); } } finalizeBaseDialog.lblDeliveryPriority.setEnabled(setPriority); finalizeBaseDialog.cbDeliveryPriority.setEnabled(setPriority); finalizeBaseDialog.lblDeliveryTime.setEnabled(!setPriority); finalizeBaseDialog.fldDeliveryTime.setEnabled(!setPriority); resetAMPM(useAmPmRadios && !setPriority); finalizeBaseDialog.lblDeliveryDate.setEnabled(clientApplicationContext .getSystemDAO().allowEditableDeliveryDate().booleanValue() && !setPriority); finalizeBaseDialog.fldDeliveryDate.setEnabled(clientApplicationContext .getSystemDAO().allowEditableDeliveryDate().booleanValue() && !setPriority); } /** * This method disables few UI components. To make all four controllers * to use this method following methods are used so that all controllers work * * enableDeliveryPanel : This method handles delivery component UI. All four * controller has specific implementation. * resetAMPM : The implementation of this method enable or disable * AM PM radio button. Current Regular and Optional * checkout controller has implementation. Rest has * empty implementation. * disableSpecificPanel : The base class implementation of this method * disables void, erase and express checkout button. * Phone room checkout has empty implementation. * Rest all use base class method. */ public void disablePanel() { logger.debug("disablePanel"); enableDeliveryPanel(false, true); finalizeBaseDialog.lblCheckBoxInstruction.setEnabled(false); finalizeBaseDialog.lblDeliveryCharge.setEnabled(false); finalizeBaseDialog.fldDeliveryCharge.setEnabled(false); finalizeBaseDialog.rbDeliveryPriority.setEnabled(false); finalizeBaseDialog.lblDeliveryPriority.setEnabled(false); finalizeBaseDialog.cbDeliveryPriority.setEnabled(false); finalizeBaseDialog.rbDeliveryTime.setEnabled(false); finalizeBaseDialog.lblDeliveryTime.setEnabled(false); finalizeBaseDialog.fldDeliveryTime.setEnabled(false); resetAMPM(false); finalizeBaseDialog.lblDeliveryDate.setEnabled(false); finalizeBaseDialog.fldDeliveryDate.setEnabled(false); finalizeBaseDialog.lblDeliveryMethod.setEnabled(false); finalizeBaseDialog.fldDeliveryMethod.setEnabled(false); finalizeBaseDialog.lblMiscAdjustments.setEnabled(false); finalizeBaseDialog.fldMiscAdjustments.setEnabled(false); finalizeBaseDialog.lblTax1.setEnabled(false); finalizeBaseDialog.cbTax1.setEnabled(false); finalizeBaseDialog.fldTax1.setEnabled(false); finalizeBaseDialog.lblTax2.setEnabled(false); finalizeBaseDialog.dlblTax2.setEnabled(false); finalizeBaseDialog.fldTax2.setEnabled(false); finalizeBaseDialog.lblRewards.setEnabled(false); finalizeBaseDialog.lblPaymentMethod.setEnabled(false); finalizeBaseDialog.lstPaymentMethod.setEnabled(false); finalizeBaseDialog.sqfPaymentMethod.setEnabled(false); finalizeBaseDialog.lblPaymentsTendered.setEnabled(false); finalizeBaseDialog.lstPaymentsTendered.setEnabled(false); finalizeBaseDialog.sqfPaymentsTendered.setEnabled(false); finalizeBaseDialog.btnRemove.setEnabled(false); finalizeBaseDialog.lblAttention.setEnabled(false); finalizeBaseDialog.fldAttention.setEnabled(false); finalizeBaseDialog.lblPONumber.setEnabled(false); finalizeBaseDialog.cbPONumber.setEnabled(false); // Fix for bug #21226, setEditable not needed // finalizeDialog.cbPONumber.setEditable(false); finalizeBaseDialog.dlblTotalAmtTendered.setEnabled(false); finalizeBaseDialog.btnPrint.setEnabled(false); finalizeBaseDialog.btnSaveInvoice.setEnabled(false); finalizeBaseDialog.btnReturnToInvoice.setEnabled(false); disableSpecificPanel(); } /** * This method handles the visibility of UI component. To make all four controllers * to use this method following methods are used so that all controllers work. * * enableDeliveryPanel : This method handles the visibility of delivery component. * All four controller implement this method. * enableSpecificPanel : This method handles very specific set of component. Phone * room controller has its own implementation. * enableSpecificPanel2 : This method handles very specific set of component. Phone * room controller has its own implementation. * isForcePost : This method determines whether invoice require force post. * Current Regular and Optional controller has its * implementation. Phone room and Non Phone room return true * as default value. * resetAMPM : The implementation of this method enable or disable AM PM * radio button. Current Regular and Optional checkout * controller has implementation. Rest has empty * implementation. * */ public void enablePanel() { logger.debug("enablePanel"); if (((invoiceListModel.getData() == null)) || (invoiceListModel.getData().size() == 0) || ((customerVO.getBillTypeCode().equals( RefBillingType.CHARGE_ONLY) && !CustomerBL .isNapaOnlineCustomer(customerVO)) || (CustomerBL .isCOD(customerVO) && invoiceVO.getSubTotal() .compareTo(MathUtil.BD_ZERO) < 0))) { enableDeliveryPanel(true, true); finalizeBaseDialog.lblCheckBoxInstruction.setEnabled(true); finalizeBaseDialog.lblDeliveryCharge.setEnabled(true); finalizeBaseDialog.fldDeliveryCharge.setEnabled(true); if (allowMiscAdj) { finalizeBaseDialog.lblMiscAdjustments.setEnabled(true); finalizeBaseDialog.fldMiscAdjustments.setEnabled(true); } else { finalizeBaseDialog.lblMiscAdjustments.setEnabled(false); finalizeBaseDialog.fldMiscAdjustments.setEnabled(false); } finalizeBaseDialog.lblTax1.setEnabled(true); finalizeBaseDialog.cbTax1.setEnabled(true); finalizeBaseDialog.lblTax2.setEnabled(true); finalizeBaseDialog.dlblTax2.setEnabled(true); finalizeBaseDialog.dlblTax2Amount.setEnabled(true); finalizeBaseDialog.lblRewards.setEnabled(true); finalizeBaseDialog.dlblRewards.setEnabled(true); if (invoiceVO.getManualTransaction().booleanValue() && !isForcePost()) { finalizeBaseDialog.fldTax1.setEnabled(true); } if ((CustomerBL.isCOD(customerVO) && invoiceVO.getSubTotal() .compareTo(MathUtil.BD_ZERO) < 0)) { finalizeBaseDialog.lblPaymentsTendered.setEnabled(true); finalizeBaseDialog.lblSeqAPLstHdr.setEnabled(true); finalizeBaseDialog.lblTenderLstHdr.setEnabled(true); finalizeBaseDialog.lblAmountLstHdr.setEnabled(true); finalizeBaseDialog.lblPaymentsTendered.setEnabled(true); finalizeBaseDialog.lstPaymentsTendered.setEnabled(true); finalizeBaseDialog.sqfPaymentsTendered.setEnabled(true); finalizeBaseDialog.btnRemove.setEnabled(true); finalizeBaseDialog.lblSequenceNumber.setEnabled(true); } else { finalizeBaseDialog.lblPaymentsTendered.setEnabled(false); finalizeBaseDialog.lblSeqAPLstHdr.setEnabled(false); finalizeBaseDialog.lblTenderLstHdr.setEnabled(false); finalizeBaseDialog.lblAmountLstHdr.setEnabled(false); finalizeBaseDialog.lblPaymentsTendered.setEnabled(false); finalizeBaseDialog.lstPaymentsTendered.setEnabled(false); finalizeBaseDialog.sqfPaymentsTendered.setEnabled(false); finalizeBaseDialog.btnRemove.setEnabled(false); finalizeBaseDialog.lblSequenceNumber.setEnabled(false); } finalizeBaseDialog.sqfPaymentsTendered.setText(""); finalizeBaseDialog.sqfPaymentMethod.setText(""); finalizeBaseDialog.lstPaymentMethod.clearSelection(); } else { enableDeliveryPanel(false, false); finalizeBaseDialog.lblCheckBoxInstruction.setEnabled(false); finalizeBaseDialog.lblDeliveryCharge.setEnabled(false); finalizeBaseDialog.fldDeliveryCharge.setEnabled(false); finalizeBaseDialog.lblMiscAdjustments.setEnabled(false); finalizeBaseDialog.fldMiscAdjustments.setEnabled(false); if (invoiceVO.getManualTransaction().booleanValue() && !isForcePost()) { finalizeBaseDialog.lblTax1.setEnabled(true); finalizeBaseDialog.cbTax1.setEnabled(true); finalizeBaseDialog.lblTax2.setEnabled(true); finalizeBaseDialog.dlblTax2.setEnabled(true); finalizeBaseDialog.dlblTax2Amount.setEnabled(true); finalizeBaseDialog.fldTax1.setEnabled(true); } else { finalizeBaseDialog.lblTax1.setEnabled(false); finalizeBaseDialog.cbTax1.setEnabled(false); finalizeBaseDialog.fldTax1.setEnabled(false); } enableSpecificPanel(); } if (isDeliveryChecked()) { finalizeBaseDialog.rbDeliveryPriority.setEnabled(true); finalizeBaseDialog.rbDeliveryTime.setEnabled(true); if (finalizeBaseDialog.rbDeliveryPriority.isSelected()) { finalizeBaseDialog.lblDeliveryPriority.setEnabled(true); finalizeBaseDialog.cbDeliveryPriority.setEnabled(true); } else { finalizeBaseDialog.lblDeliveryPriority.setEnabled(false); finalizeBaseDialog.cbDeliveryPriority.setEnabled(false); } if (finalizeBaseDialog.rbDeliveryTime.isSelected()) { finalizeBaseDialog.lblDeliveryTime.setEnabled(true); finalizeBaseDialog.fldDeliveryTime.setEnabled(true); resetAMPM(useAmPmRadios); finalizeBaseDialog.lblDeliveryDate .setEnabled(clientApplicationContext.getSystemDAO() .allowEditableDeliveryDate().booleanValue()); finalizeBaseDialog.fldDeliveryDate .setEnabled(clientApplicationContext.getSystemDAO() .allowEditableDeliveryDate().booleanValue()); } else { finalizeBaseDialog.lblDeliveryTime.setEnabled(false); finalizeBaseDialog.fldDeliveryTime.setEnabled(false); resetAMPM(false); finalizeBaseDialog.lblDeliveryDate.setEnabled(false); finalizeBaseDialog.fldDeliveryDate.setEnabled(false); } finalizeBaseDialog.lblDeliveryMethod.setEnabled(true); finalizeBaseDialog.fldDeliveryMethod.setEnabled(true); } else { finalizeBaseDialog.lblDeliveryCharge.setEnabled(false); finalizeBaseDialog.fldDeliveryCharge.setEnabled(false); finalizeBaseDialog.rbDeliveryPriority.setEnabled(false); finalizeBaseDialog.lblDeliveryPriority.setEnabled(false); finalizeBaseDialog.cbDeliveryPriority.setEnabled(false); finalizeBaseDialog.rbDeliveryTime.setEnabled(false); finalizeBaseDialog.lblDeliveryTime.setEnabled(false); finalizeBaseDialog.fldDeliveryTime.setEnabled(false); resetAMPM(false); finalizeBaseDialog.lblDeliveryDate.setEnabled(false); finalizeBaseDialog.fldDeliveryDate.setEnabled(false); finalizeBaseDialog.lblDeliveryMethod.setEnabled(false); finalizeBaseDialog.fldDeliveryMethod.setEnabled(false); } enableSpecificPanel2(); finalizeBaseDialog.lblAttention.setEnabled(true); finalizeBaseDialog.fldAttention.setEnabled(true); boolean isValidAAATransaction = invoiceVO != null && getStoreProfile().getValidateAAAcardnumber().equalsIgnoreCase("Y") && StringUtils.isNotEmpty(invoiceVO.getPONumber()) && CustomerBL.isAAACustomer(customerVO) && InvoiceBL.doesInvoiceContainPurchaseItem(invoiceVO); if (InvoiceBL.doesInvoiceContainProlinkCSGOrder(invoiceVO) || InvoiceBL.doesInvoiceContainCSGRestrictedReturnItem(invoiceVO) || isValidAAATransaction) { finalizeBaseDialog.lblPONumber.setEnabled(false); finalizeBaseDialog.cbPONumber.setEnabled(false); } else { finalizeBaseDialog.lblPONumber.setEnabled(true); finalizeBaseDialog.cbPONumber.setEnabled(true); finalizeBaseDialog.cbPONumber.setEditable(true); } finalizeBaseDialog.dlblTotalAmtTendered.setEnabled(true); checkFlagsAndSetButtons(); } /** * The base class implementation of this method disables void, * erase and express checkout button. Phone room checkout * has empty implementation. Rest all use base class method. */ public void disableSpecificPanel() { finalizeBaseDialog.btnErase.setEnabled(false); finalizeBaseDialog.btnVoid.setEnabled(false); finalizeBaseDialog.btnExpressCheckout.setEnabled(false); } /** * This method reset panel. */ public void resetPanel() { resetPanelData(); resetPanelComponents(); } /** * This method reset Attention and PO. */ private void resetAttAndPO() { finalizeBaseDialog.fldAttention.setText(""); finalizeBaseDialog.cbPONumber.removeAllItems(); ((JTextField) finalizeBaseDialog.cbPONumber.getEditor() .getEditorComponent()).setText(""); } /** * This method clears panel data. To make all four controllers to use * this method following method is used so that all controllers work. * * resetSpecificPanelData : This method clears components which are * not common across controller. */ public void resetPanelData() { finalizeBaseDialog.dlblCustomerNumAndName.setText(""); finalizeBaseDialog.dlblPhone.setText(""); finalizeBaseDialog.lblErrorMsg.setText(""); finalizeBaseDialog.dlblChangeDue.setText("0.00"); finalizeBaseDialog.dlblDeliveryCharge.setText("0.00"); finalizeBaseDialog.dlblInvoiceTotal.setText("0.00"); finalizeBaseDialog.dlblMiscAdjustments.setText("0.00"); finalizeBaseDialog.dlblRewards.setText("0.00"); finalizeBaseDialog.dlblTotalAmtTendered.setText("0.00"); finalizeBaseDialog.dlblSubtotal.setText("0.00"); finalizeBaseDialog.dlblTax1Amount.setText("0.00"); finalizeBaseDialog.dlblTax2Amount.setText("0.00"); finalizeBaseDialog.fldTax1.setText(""); finalizeBaseDialog.fldDeliveryCharge.setText(""); finalizeBaseDialog.fldDeliveryMethod.setText(""); finalizeBaseDialog.fldDeliveryTime.setText(""); finalizeBaseDialog.fldMiscAdjustments.setText(""); finalizeBaseDialog.dlblTax2.setText(""); finalizeBaseDialog.fldTax2.setText(""); blanketPO = null; resetSpecificPanelData(); } /** * This method retrieves the index of cbPrinter. * * @param printerID The id of printer. * @return the index of cbPrinter. */ private int getPrinterIndex(int printerID) { if (printerID == -1) { return 0; } int comboModelCount = finalizeBaseDialog.cbPrinter.getItemCount(); for (int i = 0; i < comboModelCount; i++) { PrinterVO printerVO = (PrinterVO) finalizeBaseDialog.cbPrinter .getItemAt(i); if (printerVO.getID() == printerID) { return i; } } return 0; } /** * This method handles few components. To make all four controllers to use * this method following method is used so that all controllers work. * * resetAMPM : The implementation of this method enable or disable AM PM * radio button. Current Regular and Optional checkout * controller has implementation. Rest has empty * implementation. */ public void resetNonTotalComponents() { finalizeBaseDialog.lblDeliveryPriority.setEnabled(isDeliveryChecked()); finalizeBaseDialog.rbDeliveryPriority.setEnabled(isDeliveryChecked()); finalizeBaseDialog.lblDeliveryPriority .setEnabled(finalizeBaseDialog.rbDeliveryPriority.isSelected() && isDeliveryChecked()); finalizeBaseDialog.cbDeliveryPriority .setEnabled(finalizeBaseDialog.rbDeliveryPriority.isSelected() && isDeliveryChecked()); finalizeBaseDialog.rbDeliveryTime.setEnabled(isDeliveryChecked()); finalizeBaseDialog.lblDeliveryTime .setEnabled(finalizeBaseDialog.rbDeliveryTime.isSelected() && isDeliveryChecked()); finalizeBaseDialog.fldDeliveryTime .setEnabled(finalizeBaseDialog.rbDeliveryTime.isSelected() && isDeliveryChecked()); finalizeBaseDialog.lblDeliveryDate.setEnabled(clientApplicationContext .getSystemDAO().allowEditableDeliveryDate().booleanValue() && isDeliveryChecked() && finalizeBaseDialog.rbDeliveryTime.isSelected()); finalizeBaseDialog.fldDeliveryDate.setEnabled(clientApplicationContext .getSystemDAO().allowEditableDeliveryDate().booleanValue() && isDeliveryChecked() && finalizeBaseDialog.rbDeliveryTime.isSelected()); finalizeBaseDialog.lblDeliveryMethod.setEnabled(isDeliveryChecked()); finalizeBaseDialog.fldDeliveryMethod.setEnabled(isDeliveryChecked()); finalizeBaseDialog.lblAttention.setEnabled(true); finalizeBaseDialog.fldAttention.setEnabled(true); finalizeBaseDialog.lblPONumber.setEnabled(true); // the cbPONumber field is set this way because of a problem clearing a // PO Num from // a previous invoice. bug #13715 String strPO = ((JTextField) finalizeBaseDialog.cbPONumber.getEditor() .getEditorComponent()).getText(); finalizeBaseDialog.cbPONumber.setEnabled(true); finalizeBaseDialog.cbPONumber.setEditable(true); ((JTextField) finalizeBaseDialog.cbPONumber.getEditor() .getEditorComponent()).setText(strPO); finalizeBaseDialog.cbPrinter.setEnabled(!invoiceVO.getManualTransaction().booleanValue()); finalizeBaseDialog.lblErrorMsg.setText(""); resetAMPM(useAmPmRadios && finalizeBaseDialog.rbDeliveryTime.isSelected() && isDeliveryChecked()); } /** * This method handles few components. To make all four controllers to use this * method following methods are used so that all controllers work. * * enableDeliveryPanel : This method handles the visibility of delivery * component. All four controller implement this method. * setDelivery : This method set the delivery component for each * controller. This is used since three types of UI * component is used for delivery among all controllers. * resetAMPM : The implementation of this method enable or disable * AM PM radio button. Current Regular and Optional * checkout controller has implementation. Rest has empty * implementation. * isDeliveryChecked : This method checks if delivery is applied . All four * controllers implement this method. * isInvoicePaidInFull : This method checks whether invoice is paid fully. * Current Regular controller has specific implementation. * Rest all use base class implementation. */ public void resetPanelComponents() { logger.info("resetPanelComponents"); // set the am pm button stuff to disabled if using french canadian if (useMilitaryTime() || (clientApplicationContext.getCurrentLocale().getLanguage() .equalsIgnoreCase(RefLanguage.FRENCH) && (clientApplicationContext .getCurrentLocale().getCountry() .equalsIgnoreCase(RefCountry.CANADA)))) { useAmPmRadios = false; } finalizeBaseDialog.lblErrorMsg.setText(""); enableDeliveryPanel(true, false); finalizeBaseDialog.lblCheckBoxInstruction.setEnabled(true); if (deliveryFlag.equals("N")) { setDelivery(false); finalizeBaseDialog.rbDeliveryPriority.setEnabled(false); finalizeBaseDialog.lblDeliveryPriority.setEnabled(false); finalizeBaseDialog.cbDeliveryPriority.setEnabled(false); finalizeBaseDialog.rbDeliveryTime.setEnabled(false); finalizeBaseDialog.lblDeliveryTime.setEnabled(false); finalizeBaseDialog.fldDeliveryTime.setEnabled(false); resetAMPM(false); finalizeBaseDialog.lblDeliveryDate.setEnabled(false); finalizeBaseDialog.fldDeliveryDate.setEnabled(false); finalizeBaseDialog.lblDeliveryMethod.setEnabled(false); finalizeBaseDialog.fldDeliveryMethod.setEnabled(false); } else { if (deliveryFlag.equals("A")) { setDelivery(true); } BigDecimal minAmtForFreeDelivery = (customerDeliveryVO == null) ? null : customerDeliveryVO.getMinAmtFreeDelivery(); if ((minAmtForFreeDelivery == null) || (minAmtForFreeDelivery.doubleValue() == (double) 0.00)) { finalizeBaseDialog.lblDeliveryCharge.setEnabled(false); finalizeBaseDialog.fldDeliveryCharge.setEnabled(false); } finalizeBaseDialog.lblDeliveryPriority .setEnabled(isDeliveryChecked()); finalizeBaseDialog.rbDeliveryPriority .setEnabled(isDeliveryChecked()); finalizeBaseDialog.lblDeliveryPriority .setEnabled(finalizeBaseDialog.rbDeliveryPriority .isSelected() && isDeliveryChecked()); finalizeBaseDialog.cbDeliveryPriority .setEnabled(finalizeBaseDialog.rbDeliveryPriority .isSelected() && isDeliveryChecked()); finalizeBaseDialog.rbDeliveryTime.setEnabled(isDeliveryChecked()); finalizeBaseDialog.lblDeliveryTime .setEnabled(finalizeBaseDialog.rbDeliveryTime.isSelected() && isDeliveryChecked()); finalizeBaseDialog.fldDeliveryTime .setEnabled(finalizeBaseDialog.rbDeliveryTime.isSelected() && isDeliveryChecked()); resetAMPM(useAmPmRadios && finalizeBaseDialog.rbDeliveryTime.isSelected() && isDeliveryChecked()); finalizeBaseDialog.lblDeliveryDate .setEnabled(clientApplicationContext.getSystemDAO() .allowEditableDeliveryDate().booleanValue() && isDeliveryChecked() && finalizeBaseDialog.rbDeliveryTime.isSelected()); finalizeBaseDialog.fldDeliveryDate .setEnabled(clientApplicationContext.getSystemDAO() .allowEditableDeliveryDate().booleanValue() && isDeliveryChecked() && finalizeBaseDialog.rbDeliveryTime.isSelected()); finalizeBaseDialog.lblDeliveryMethod .setEnabled(isDeliveryChecked()); finalizeBaseDialog.fldDeliveryMethod .setEnabled(isDeliveryChecked()); } finalizeBaseDialog.lblAttention.setEnabled(true); finalizeBaseDialog.fldAttention.setEnabled(true); finalizeBaseDialog.lblPONumber.setEnabled(true); finalizeBaseDialog.cbPONumber.setEnabled(true); finalizeBaseDialog.cbPONumber.setEditable(true); finalizeBaseDialog.lblMiscAdjustments.setEnabled(true); finalizeBaseDialog.fldMiscAdjustments.setEnabled(true); finalizeBaseDialog.lblRewards.setEnabled(true); finalizeBaseDialog.lblTax1.setEnabled(true); finalizeBaseDialog.cbTax1.setEnabled(true); finalizeBaseDialog.lblTax2.setEnabled(true); finalizeBaseDialog.dlblTax2.setEnabled(true); finalizeBaseDialog.lblPaymentMethod.setEnabled(true); finalizeBaseDialog.lstPaymentMethod.setEnabled(true); finalizeBaseDialog.sqfPaymentMethod.setEnabled(true); if ((invoiceListModel.getData() == null) || (invoiceListModel.getData().size() == 0)) { finalizeBaseDialog.lblPaymentsTendered.setEnabled(false); finalizeBaseDialog.lblSeqAPLstHdr.setEnabled(false); finalizeBaseDialog.lblTenderLstHdr.setEnabled(false); finalizeBaseDialog.lblAmountLstHdr.setEnabled(false); finalizeBaseDialog.lblPaymentsTendered.setEnabled(false); finalizeBaseDialog.lstPaymentsTendered.setEnabled(false); finalizeBaseDialog.sqfPaymentsTendered.setEnabled(false); finalizeBaseDialog.btnRemove.setEnabled(false); } else { finalizeBaseDialog.lblPaymentsTendered.setEnabled(true); finalizeBaseDialog.lblSeqAPLstHdr.setEnabled(true); finalizeBaseDialog.lblTenderLstHdr.setEnabled(true); finalizeBaseDialog.lblAmountLstHdr.setEnabled(true); finalizeBaseDialog.lblPaymentsTendered.setEnabled(true); finalizeBaseDialog.lstPaymentsTendered.setEnabled(true); finalizeBaseDialog.sqfPaymentsTendered.setEnabled(true); finalizeBaseDialog.btnRemove.setEnabled(true); } finalizeBaseDialog.dlblTotalAmtTendered.setEnabled(true); if ((invoiceVO == null) || !invoiceVO.getManualTransaction().booleanValue()) { finalizeBaseDialog.cbPrinter.setEnabled(true); } else { finalizeBaseDialog.cbPrinter.setEnabled(false); } finalizeBaseDialog.btnPrint.setEnabled(isInvoicePaidInFull()); checkFlagsAndSetButtons(); payPanel.taRewardMessage.setVisible(false); } /** * This method handles visibility of Primary Tax. * @param enabled */ private void enableTax1(boolean enabled) { finalizeBaseDialog.lblTax1.setEnabled(enabled); finalizeBaseDialog.cbTax1.setEnabled(enabled); finalizeBaseDialog.dlblTax1Amount.setEnabled(enabled); finalizeBaseDialog.fldTax1.setEnabled(enabled); } /** * This method handles visibility of Secondary Tax. * @param enabled */ private void enableTax2(boolean enabled) { finalizeBaseDialog.lblTax2.setEnabled(enabled); finalizeBaseDialog.dlblTax2.setEnabled(enabled); finalizeBaseDialog.dlblTax2Amount.setEnabled(enabled); finalizeBaseDialog.fldTax2.setEnabled(enabled); } /** * * @return true if credit is good, false if over limit */ boolean checkCredit() { final BigDecimal subTotal = invoiceVO.getSubTotal(); logger.debug("----- inside checkCredit, subtotal= " + subTotal.toString()); if (subTotal.signum() <= 0) { logger.debug("----- checkCredit: subTotal.compareTo(bdZero) <= 0"); return true; } final Object[] availAndLimit = CustomerBL .getAvailableCreditAndLimit(customerVO); int creditLimit = 0; try { creditLimit = Integer.parseInt((String) availAndLimit[0]); } catch (NumberFormatException e) { // there is no credit limit so return true return true; } logger.debug("----- inside checkCredit, creditLimit= " + creditLimit); if (creditLimit == 0) { return true; } final BigDecimal bdOrigAvailable = new BigDecimal( availAndLimit[2].toString()); final BigDecimal bdNewAvailable = bdOrigAvailable.subtract(subTotal); final BigDecimal currentBalance = (BigDecimal) availAndLimit[3]; // is the customer over the credit limit? boolean retFlag = true; if (creditLimit > 0 && bdNewAvailable.signum() < 0) { // # 28527 Changed the code to calculate cardBalance. boolean askPassword = clientApplicationContext.getSystemDAO() .askForPassword(PasswordConstants.CREDIT_LIMIT_PWD) .booleanValue(); // bug #31302, passing Customer Credit Limit to the setInitialData() passwordController.showCreditLimitExceededMsg( PasswordConstants.CREDIT_LIMIT_PWD, currentBalance, askPassword); passwordController.setViewVisible(true); retFlag = passwordController.getPasswordValid(); } logger.debug("----- checkCredit return= " + retFlag); return retFlag; } /** * This method validates Delivery Date. * * @return true if validation succeeds. */ private boolean validateDeliveryDate() { Date deliveryDate = parseDate(finalizeBaseDialog.fldDeliveryDate .getText()); boolean retFlag = true; if (deliveryDate == null) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "122"); retFlag = false; } if (retFlag) { Calendar calDelivery = Calendar .getInstance(clientApplicationContext.getCurrentLocale()); Calendar calCurrent = Calendar.getInstance(clientApplicationContext .getCurrentLocale()); Calendar calTemp = Calendar.getInstance(clientApplicationContext .getCurrentLocale()); String strDeliveryDate = finalizeBaseDialog.fldDeliveryDate .getText(); calDelivery.setTime(parseDate(strDeliveryDate)); calDelivery.set(calDelivery.get(Calendar.YEAR), calDelivery.get(Calendar.MONTH), calDelivery.get(Calendar.DATE), 0, 0, 0); calDelivery.set(Calendar.MILLISECOND, 0); calCurrent.set(calCurrent.get(Calendar.YEAR), calCurrent.get(Calendar.MONTH), calCurrent.get(Calendar.DATE), 0, 0, 0); calCurrent.set(Calendar.MILLISECOND, 0); if (calDelivery.before(calCurrent)) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "1240"); retFlag = false; } if (retFlag) { calTemp.set(calTemp.get(Calendar.YEAR), calTemp.get(Calendar.MONTH), calTemp.get(Calendar.DATE), 0, 0, 0); calTemp.set(Calendar.MILLISECOND, 0); calTemp.add(Calendar.DATE, 7); if (calDelivery.after(calTemp)) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "1380"); retFlag = false; } } } return retFlag; } /** * @return useMilitaryTime flag value. */ protected boolean useMilitaryTime() { return clientApplicationContext .getProfile(Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()) .getStoreProfile().getUseMilitaryTime().booleanValue(); } /** * This methods validates Delivery Time. To make all four controllers to use * this method following methods are used so that all controllers work. * * isTimeNotEntered : This method validates whether time is entered or not. * Current Regular and Optional controller have common * implementation. Rest returns 'true' as default value. * processDateToValidate : This method parse time. Current Regular and * Optional controller has similar implementation. Phone * room and Non phone room has common implementation. * * getMessageId : This method returns specific message id. Current * Regular and Optional controller has similar * implementation. Phone room and Non phone room * has common implementation. * * isTimeRequireSpace : This method checks whether a time ends with space. * Current Regular and Optional controller has similar * implementation. Phone room and Non phone room has * common implementation. * @return */ private boolean validateDeliveryTime() { // called from validateComponent method. String strChar = ":"; String strSuffix = ""; int index = -1; int indexOfh = -1; String strTime = ""; String strTemp = finalizeBaseDialog.fldDeliveryTime.getText(); bUse24HrsTime = false; if (strTemp == null) { return false; } if (clientApplicationContext.getCurrentLocale().getLanguage() .equalsIgnoreCase(RefLanguage.FRENCH) && (clientApplicationContext.getCurrentLocale().getCountry() .equalsIgnoreCase(RefCountry.CANADA))) { bUse24HrsTime = true; locale = new Locale("fr", "CA"); } else { locale = new Locale("en", "US"); } // for a locale of French, 'h' is used instead of a colon. if (bUse24HrsTime) { strChar = "h"; } else { strChar = ":"; } // if locale is US, look for AM/PM if (bUse24HrsTime) { indexOfh = strTemp.indexOf(strChar); } else { if (strTemp.endsWith("AM")) { index = strTemp.indexOf("AM"); strSuffix = strTemp.substring(index, strTemp.length()); } else if (strTemp.endsWith("am")) { index = strTemp.indexOf("am"); strSuffix = strTemp.substring(index, strTemp.length()); } else if (strTemp.endsWith("PM")) { index = strTemp.indexOf("PM"); strSuffix = strTemp.substring(index, strTemp.length()); } else if (strTemp.endsWith("pm")) { index = strTemp.indexOf("pm"); strSuffix = strTemp.substring(index, strTemp.length()); } } logger.debug("useMilitaryTime= " + useMilitaryTime()); if (useMilitaryTime()) { if (index >= 0) { // if AM/PM found, not needed. // message = "Invalid time entered. AM/PM not required." clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "1244"); return false; } else { // index <0, AM/PM not found, not needed only need HH:MM if (strTemp.indexOf(":") <= 0) { // message = "Invalid time entered. HH:MM format required." clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "1244"); return false; } } } else if (bUse24HrsTime) { if (indexOfh <= 0) {// 'h' not found clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "2265"); return false; } } else { if (index <= 0) { // AM/PM *not* found // if time is not entered at all if (isTimeNotEntered(strTemp)) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "1245"); return false; } // not requiring AM/PM - using radio buttons instead String stringSuf = ""; if (finalizeBaseDialog.rbAM.isSelected()) { strSuffix = "AM"; } else { // stringSuf = "PM"; strSuffix = "PM"; } } else { if (strTemp.indexOf(":") <= 0) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "1245"); return false; } } } String strHours = null; String strMinutes = null; if (bUse24HrsTime) { if (indexOfh > 0) { strTime = strTemp.trim(); strHours = strTemp.substring(0, indexOfh).trim(); strMinutes = strTemp.substring(strTemp.indexOf(strChar) + 1) .trim(); } } else { // this will remove the 'AM'/'PM' text and leave the time for // posting. if (index >= 0) { strTime = strTemp.substring(0, index); } else { strTime = strTemp; } logger.debug("strTime= " + strTime + " strSuffix= " + strSuffix); strHours = strTime.substring(0, strTime.indexOf(strChar)); strMinutes = strTime.substring(strTime.indexOf(strChar) + 1); } logger.debug("strTime= " + strTime + " strSuffix= " + strSuffix); int hours = 0; int minutes = 0; try { hours = Integer.parseInt(strHours.trim()); minutes = Integer.parseInt(strMinutes.trim()); } catch (NumberFormatException ne) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "2266"); logger.debug(ne.getMessage(), ne); return false; } if (useMilitaryTime()) { if (hours < 0 || hours > 23) { // #260 = 0,N,Hour must be in the range 0-23 and Minute 0-59. clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "260"); return false; } } else if (bUse24HrsTime) { if ((hours < 0 || hours > 23)) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "260"); return false; } } else { if (hours < 1 || hours > 12) { // #1350 Hour must be in the range 1-12 and Minute 0-59. clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "1350"); return false; } } if (minutes < 0 || minutes > 59) { // #260 = 0,N,Hour must be in the range 0-23 and Minute 0-59. clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "260"); return false; } Calendar calDelivery = Calendar.getInstance(locale); Calendar tempDelivery = Calendar.getInstance(locale); Date d = processDateToValidate(strSuffix, strTime, strTemp); if (d == null) { if (bUse24HrsTime) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "2265"); } else { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, getMessageId()); } return false; } calDelivery.setTime(d); d = parseDate(finalizeBaseDialog.fldDeliveryDate.getText()); if (d == null) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "1244"); return false; } tempDelivery.setTime(d); calDelivery.set(tempDelivery.get(Calendar.YEAR), tempDelivery.get(Calendar.MONTH), tempDelivery.get(Calendar.DATE)); Calendar calCurrent = Calendar.getInstance(clientApplicationContext .getCurrentLocale()); if (calDelivery.before(calCurrent)) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "1370"); return false; } if (isTimeRequireSpace(strSuffix, strTime)) { logger.info("strSuffix = " + strSuffix); strTime += " "; } finalizeBaseDialog.fldDeliveryTime.setText(strTime + strSuffix); // finalizeDialog.fldDeliveryTime.setText(strTime + strSuffix); return true; } /** * This method place focus to a specific component. To make all four controllers * to use this method following method is used so that all controllers work. * decideSpecificAndPlaceFocus : The controllers which have their own way of * placing focus override this method to their use. */ private void decideAndPlaceFocus() { if (CustomerBL.isNapaOnlineCustomer(customerVO)) { if (invoiceVO.getManualTransaction().booleanValue()) { finalizeBaseDialog.btnPrint.requestFocus(); } else { finalizeBaseDialog.cbPrinter.requestFocus(); } } else if (invoiceVO.getManualTransaction().booleanValue() && finalizeBaseDialog.fldTax1.isEnabled()) { finalizeBaseDialog.fldTax1.requestFocus(); } else { decideSpecificAndPlaceFocus(); } } /* * (non-Javadoc) * * @see * java.awt.event.WindowListener#windowOpened(java.awt.event.WindowEvent) */ public void windowOpened(WindowEvent we) { decideAndPlaceFocus(); } /* * (non-Javadoc) * * @see * com.gpc.client.common.event.CustomerListener#customerChanged(com.gpc. * client.common.event.CustomerEvent) */ public void customerChanged(CustomerEvent ce) { customerVO = (CustomerVO) ce.getModel(); finalizeBaseDialog.cbPONumber.removeAllItems(); phoneNumberController.phoneNumberDialog.fldPhoneNumber.setText(""); ((JTextField) finalizeBaseDialog.cbPONumber.getEditor() .getEditorComponent()).setText(""); loyaltyCustomerLookup = null; } /* * (non-Javadoc) * * @see * com.gpc.client.common.event.InvoiceListener#manualInvoiceOpened(com.gpc * .client.common.event.InvoiceEvent) */ public void manualInvoiceOpened(InvoiceEvent ie) { finalizeBaseDialog.cbTax1.setVisible(true); finalizeBaseDialog.fldTax1.setVisible(true); finalizeBaseDialog.fldTax2.setVisible(true); finalizeBaseDialog.dlblTax2.setVisible(false); if (invoiceVO != null) { invoiceVO.setManualTransaction(Boolean.TRUE); } } /* * (non-Javadoc) * * @see * com.gpc.client.common.event.InvoiceListener#manualInvoiceClosed(com.gpc * .client.common.event.InvoiceEvent) */ public void manualInvoiceClosed(InvoiceEvent ie) { logger.debug("=====>> IN manualInvoiceClosed() !"); finalizeBaseDialog.cbTax1.setVisible(true); finalizeBaseDialog.fldTax1.setVisible(false); finalizeBaseDialog.fldTax2.setVisible(false); finalizeBaseDialog.dlblTax2.setVisible(true); finalizeBaseDialog.fldTax2.setVisible(false); finalizeBaseDialog.dlblTax2.setVisible(true); if (invoiceVO != null) { invoiceVO.setManualTransaction(Boolean.FALSE); } } /* (non-Javadoc) * @see java.awt.event.FocusListener#focusLost(java.awt.event.FocusEvent) * * To make all four controllers to use this method, following methods are * used so that all controllers work. * setSpecificInputVerifier : This method has implementation in Regular * and Optional Checkout controller. Rest has * empty implementation. * handleFldDeliveryTimeFocusLost : This method has implementation in Regular * and Optional Checkout controller. Rest has * empty implementation. */ public void focusLost(FocusEvent fe) { if (fe.getComponent().getName() == null) { return; } if (fe.getComponent().getName().equals("rbDeliveryTime")) { finalizeBaseDialog.fldDeliveryDate .setVerifyInputWhenFocusTarget(true); finalizeBaseDialog.fldDeliveryTime .setVerifyInputWhenFocusTarget(true); finalizeBaseDialog.rbDeliveryPriority .setVerifyInputWhenFocusTarget(true); setSpecificInputVerifier(true); } else if (fe.getComponent().getName().equals("fldDeliveryDate")) { finalizeBaseDialog.fldDeliveryDate .setVerifyInputWhenFocusTarget(true); finalizeBaseDialog.fldDeliveryTime .setVerifyInputWhenFocusTarget(true); finalizeBaseDialog.rbDeliveryPriority .setVerifyInputWhenFocusTarget(true); setSpecificInputVerifier(true); } else if (fe.getComponent().getName().equals("fldDeliveryTime")) { finalizeBaseDialog.fldDeliveryDate .setVerifyInputWhenFocusTarget(true); finalizeBaseDialog.fldDeliveryTime .setVerifyInputWhenFocusTarget(true); finalizeBaseDialog.rbDeliveryPriority .setVerifyInputWhenFocusTarget(true); setSpecificInputVerifier(true); handleFldDeliveryTimeFocusLost(); } else if ((fe.getComponent().getName().equals("rbAM") || fe .getComponent().getName().equals("rbPM"))) { finalizeBaseDialog.fldDeliveryDate .setVerifyInputWhenFocusTarget(true); finalizeBaseDialog.fldDeliveryTime .setVerifyInputWhenFocusTarget(true); finalizeBaseDialog.rbDeliveryPriority .setVerifyInputWhenFocusTarget(true); finalizeBaseDialog.rbAM.setVerifyInputWhenFocusTarget(true); finalizeBaseDialog.rbPM.setVerifyInputWhenFocusTarget(true); } else if ((fe.getComponent().getName().equals("rbDeliveryYes") || fe .getComponent().getName().equals("rbDeliveryNo"))) { finalizeBaseDialog.fldDeliveryDate .setVerifyInputWhenFocusTarget(true); finalizeBaseDialog.fldDeliveryTime .setVerifyInputWhenFocusTarget(true); finalizeBaseDialog.rbDeliveryPriority .setVerifyInputWhenFocusTarget(true); finalizeBaseDialog.rbAM.setVerifyInputWhenFocusTarget(true); finalizeBaseDialog.rbPM.setVerifyInputWhenFocusTarget(true); finalizeBaseDialog.rbDeliveryYes .setVerifyInputWhenFocusTarget(true); finalizeBaseDialog.rbDeliveryNo.setVerifyInputWhenFocusTarget(true); } } /* * (non-Javadoc) * * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent) * To make all four controllers to use this method following methods are used * so that all controllers work. * * isOptionalDelivery : This method check whether optional delivery flag * is enabled. Current Optional controller implement * this method. Rest all use base controller method * which return 'false'. * * validatePODelivery : This method delegates call to a different method * to validate PO and Delivery. Regular and Optional * controller return true. Rest all delegates call * to another method to validate PO and Delivery. * * handleSpecificMouseClick : This method handles specific mouse click events. * Regular controller has empty implementation. Rest * all has their own implementation. */ public void mouseClicked(MouseEvent me) { Component glassPane = finalizeBaseDialog.getGlassPane(); if (me.getSource() == glassPane) { Toolkit.getDefaultToolkit().beep(); me.consume(); return; } if (me.getSource() instanceof JComponent) { JComponent source = (JComponent) me.getSource(); if (source.getName().equals("lstPaymentMethod") && me.getClickCount() == 2) { if (isOptionalDelivery()) { finalizeBaseDialog.lstPaymentMethod.clearSelection(); finalizeBaseDialog.sqfPaymentMethod.setText(""); finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } else { if (validatePODelivery(true)) { finalizeBaseDialog.sqfPaymentMethod .dispatchEvent(pressTabKey(finalizeBaseDialog.sqfPaymentMethod)); } } //dblclick on payment method in left panel. need to hide the right panel if (RefStoreConfigurationUtil.isRefundTenderRestrictionEnabled()) { if (invoiceVO != null && invoiceVO.getInvoiceTotal().signum() < 0) { payPanel.pnlTenderTypes.setVisible(false); } } } if (source.getName().equals("lstPaymentMethod") && me.getClickCount() == 1) { if (!isOptionalDelivery()) { if (validatePODelivery(true)) { Object oSelected = finalizeBaseDialog.lstPaymentMethod .getSelectedValue(); IDValuePairVO item = (IDValuePairVO) oSelected; if (item != null && !(isValidPaymentMethod((Short) item.getID()))) { finalizeBaseDialog.lstPaymentMethod .clearSelection(); finalizeBaseDialog.sqfPaymentMethod.setText(""); } } } else { finalizeBaseDialog.lstPaymentMethod.clearSelection(); finalizeBaseDialog.sqfPaymentMethod.setText(""); } } handleSpecificMouseClick(source, me); if (!(source.getName().equals("lstPaymentsTendered"))) { finalizeBaseDialog.lstPaymentsTendered.clearSelection(); } } } /* * (non-Javadoc) * * @see * java.awt.event.WindowListener#windowClosing(java.awt.event.WindowEvent) */ public void windowClosing(WindowEvent we) { if (!finalizeBaseDialog.btnReturnToInvoice.isEnabled()) { finalizeBaseDialog .setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); } else { finalizeBaseDialog.btnReturnToInvoice.doClick(); if (!canPerformCancelEraseButtonAction()) { finalizeBaseDialog .setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); } if (GiftCardBL.doesInvoiceContainsActivatedOrReloadedGC(invoiceVO)) { finalizeBaseDialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); } } } /* * (non-Javadoc) * * @see * java.awt.event.WindowListener#windowActivated(java.awt.event.WindowEvent) */ public void windowActivated(WindowEvent we) { if (processingThread != null && !processingThread.isAlive()) { processingThread.start(); } } /* * (non-Javadoc) * * @see com.gpc.client.pointofsale.util.BaseController#localizeView() * Phone room controller has its own implementation which eventually call base * class implementation before performing specific business. To make all four * controllers to use this method following methods are used so that all * controllers work. * * localizeSpecificView : This method performs localization for properties * which are not common across all controller. Phone * room controller has its own implementation. * * getDialogName : This method returns the dialog name of individual * controller. */ public void localizeView() { notAssigned = clientApplicationContext.getResourceBundleReader() .getLocalizedText(ResourceBundleReader.UI, "ComboBoxNotAssigned", clientApplicationContext.getCurrentLocale()); localizeSpecificView(); // Sets the property key to the panel title Border before the // FwoLocalizationMgr // framework class methods are called to localize the panel title // border. setTitleBorderPropertyKey(); localizationMgr.localize(finalizeBaseDialog, getDialogName()); localizationMgr.localize(finalizeBaseDialog.pnlSubtotal, getDialogName()); localizationMgr.localize(finalizeBaseDialog.pnlAlternateCoreSubtotal, getDialogName()); localizationMgr.localize(finalizeBaseDialog.pnlDelivery, getDialogName()); localizationMgr.localize(finalizeBaseDialog.pnlTax, getDialogName()); localizationMgr.localize(finalizeBaseDialog.pnlMiscellaneous, getDialogName()); localizationMgr.localize(finalizeBaseDialog.pnlTender, getDialogName()); localizationMgr.localize(finalizeBaseDialog.pnlPaymentsTenderedLstHdr, getDialogName()); localizationMgr.localize(finalizeBaseDialog.pnlSelectPrinter, getDialogName()); localizationMgr.localize(finalizeBaseDialog.pnlInvoiceTotal, getDialogName()); localizationMgr.localize(finalizeBaseDialog.pnlChangeDue, getDialogName()); localizationMgr.localize(finalizeBaseDialog.pnlFinalizeInvoice, getDialogName()); localizationMgr.localize(finalizeBaseDialog.pnlTotalAmtTendered, getDialogName()); strProcessingForAuthorization = clientApplicationContext .getResourceBundleReader().getLocalizedText( ResourceBundleReader.UI, getDialogName() + ".ProcessingForAuthorization", clientApplicationContext.getCurrentLocale()); strPostingAndPrintingInProgressMessage = clientApplicationContext .getResourceBundleReader().getLocalizedText( ResourceBundleReader.UI, getDialogName() + ".PostingAndPringtingInProgress", clientApplicationContext.getCurrentLocale()); strPORequired = clientApplicationContext.getResourceBundleReader() .getLocalizedText(ResourceBundleReader.UI, getDialogName() + ".PORequired", clientApplicationContext.getCurrentLocale()); strAttentionRequired = clientApplicationContext .getResourceBundleReader().getLocalizedText( ResourceBundleReader.UI, getDialogName() + ".AttentionRequired", clientApplicationContext.getCurrentLocale()); strMustSignReceipt = clientApplicationContext.getResourceBundleReader() .getLocalizedText(ResourceBundleReader.UI, getDialogName() + ".MustSignReceipt", clientApplicationContext.getCurrentLocale()); strMustSignRefund = clientApplicationContext.getResourceBundleReader() .getLocalizedText(ResourceBundleReader.UI, getDialogName() + ".MustSignRefund", clientApplicationContext.getCurrentLocale()); strBlanketPOExpired = clientApplicationContext .getResourceBundleReader().getLocalizedText( ResourceBundleReader.UI, getDialogName() + ".BlanketPOExpired", clientApplicationContext.getCurrentLocale()); strMustEnterDeliveryDate = clientApplicationContext .getResourceBundleReader().getLocalizedText( ResourceBundleReader.UI, getDialogName() + ".MustEnterDeliveryDate", clientApplicationContext.getCurrentLocale()); strMustEnterDeliveryTime = clientApplicationContext .getResourceBundleReader().getLocalizedText( ResourceBundleReader.UI, getDialogName() + ".MustEnterDeliveryTime", clientApplicationContext.getCurrentLocale()); strMustEnterDeliveryMethod = clientApplicationContext .getResourceBundleReader().getLocalizedText( ResourceBundleReader.UI, getDialogName() + ".MustEnterDeliveryMethod", clientApplicationContext.getCurrentLocale()); strDeliveryMethod = clientApplicationContext.getResourceBundleReader() .getLocalizedText(ResourceBundleReader.UI, getDialogName() + ".fldDeliveryMethod", clientApplicationContext.getCurrentLocale()); strNoPayMethod = clientApplicationContext.getResourceBundleReader() .getLocalizedText(ResourceBundleReader.UI, getDialogName() + ".noPayMethod", clientApplicationContext.getCurrentLocale()); finalizeBaseDialog.fldDeliveryTime.setDocument(new TimeTextDocument()); // set the am pm button stuff to disabled if using french canadian if (useMilitaryTime() || (clientApplicationContext.getCurrentLocale().getLanguage() .equalsIgnoreCase(RefLanguage.FRENCH) && (clientApplicationContext .getCurrentLocale().getCountry() .equalsIgnoreCase(RefCountry.CANADA)))) { useAmPmRadios = false; } } /** * This method sets the panel title border property key. */ private void setTitleBorderPropertyKey() { final Border border = finalizeBaseDialog.pnlDelivery.getBorder(); if (border instanceof TitledBorder) { ((TitledBorder) border) .setTitle(FinalizeBaseDialog.DELIVERY_OPTIONS_PANEL_TITLE); } } /** * This method displays customer information. Regular and Optional controller * has its own implementation which eventually calls base class method and * then perform few specific business. */ protected void displayCustomerInfo() { StringBuffer sb = new StringBuffer(); if (customerVO.getCustomerNumber() != null) { sb.append(customerVO.getCustomerNumber().intValue() + " - "); } if (customerVO.getName() != null) { sb.append(customerVO.getName()); } finalizeBaseDialog.dlblCustomerNumAndName.setText(sb.toString()); if (customerVO.getPhone() != null) { finalizeBaseDialog.dlblPhone.setText(getCustomerPhone()); } } /** * This method formats the customer phone number. Phone * room controller has its own implementation. * @return */ protected String getCustomerPhone() { String retValue = ""; Locale recordLocale = null; if (customerVO != null && customerVO.getRefLanguageCD() != null && customerVO.getCountryCD() != null) { recordLocale = new Locale(customerVO.getRefLanguageCD(), customerVO.getCountryCD()); } recordLocale = recordLocale == null ? clientApplicationContext .getCurrentLocale() : recordLocale; FwoPhonePattern fwoPhonePattern = (FwoPhonePattern) FwoPattern .getPhonePatternInstance(recordLocale); try { retValue = fwoPhonePattern.format(customerVO.getPhone()); } catch (PhonePatternFormatException phonePatternFormatException) { retValue = customerVO.getPhone(); } return retValue; } /** * This method returns the POSPricingClient. * * @return POSPricingClient * @throws RemoteException */ private POSPricingClient getRMIClient() throws RemoteException { if (posPricingClient == null) { posPricingClient = new POSPricingClient(FwoUtil.getIPAddress()); } return posPricingClient; } /** * This method creates Rads Discrepancy Log. * * @param invoice * Contains invoice information. * @param radsDiscrepancyLogsFromInvoice * List containing the rads discrepancy retrieved from Invoice VO */ private void createRadsDiscrepancyLog(InvoiceVO invoice, List radsDiscrepancyLogsFromInvoice) { List radsDiscrepancyLogList = new ArrayList(); if (invoice != null && invoiceVO.getLineItems() != null) { Vector lineItems = invoiceVO.getLineItems(); int lineItemSize = 0; int locationId = (invoiceVO.getLOC() != null) ? (invoiceVO.getLOC() .intValue()) : 1; lineItemSize = lineItems.size(); for (int index = 0; index < lineItemSize; index++) { Object object = lineItems.elementAt(index); if (object instanceof BaseLineItemVO) { BaseLineItemVO baseLineItem = (BaseLineItemVO) object; InvoiceBL.createRadsDiscrepancyLogList(locationId, baseLineItem, radsDiscrepancyLogList, RefRadsDiscrepancyType.INVOICE_CANCELLED); } } } int radsDiscrepancyLogsSize = (radsDiscrepancyLogsFromInvoice != null) ? radsDiscrepancyLogsFromInvoice .size() : 0; /* * The discrepancy list from Invoice VO contain discrepancy for the * deleted line items. since the invoice is canceled the discrepancy * should be of discrepancy type "Invoice Canceled" instead of "picked * by line items deleted" */ for (int index = 0; index < radsDiscrepancyLogsSize; index++) { Object object = radsDiscrepancyLogsFromInvoice.get(index); if (object instanceof RadsDiscrepancyLog) { RadsDiscrepancyLog radsDiscrepancyLog = (RadsDiscrepancyLog) object; radsDiscrepancyLog .setDiscrepancyType(RefRadsDiscrepancyType.INVOICE_CANCELLED); } } if ((radsDiscrepancyLogsFromInvoice != null && radsDiscrepancyLogsFromInvoice .size() > 0) || (radsDiscrepancyLogList != null && radsDiscrepancyLogList .size() > 0)) { logger.debug("Call of service method to create discrepancy log"); try { logger.debug("invoiceVO.getRadsDiscrepancyLogList() -->" + invoiceVO.getRadsDiscrepancyLogList()); if (radsDiscrepancyLogsFromInvoice != null) { if (radsDiscrepancyLogList == null) { radsDiscrepancyLogList = new ArrayList(); } radsDiscrepancyLogList .addAll(radsDiscrepancyLogsFromInvoice); } RadsServiceFactory.getServiceInstance() .createRadsDiscrepancyLog(radsDiscrepancyLogList); } catch (ApplicationException e) { logger.error( "Exception occurred while creating discrepancy log for cancelled invoice line item", e); clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "9039"); } } radsDiscrepancyLogList = null; } /** * This method validates which component is not validated in sequence * of PO Number and Delivery field * * @return Component which is not validated */ protected JComponent getPODeliveryComponentIfNotValidated() { JComponent validateComponent = null; String sPO = ((JTextField) finalizeBaseDialog.cbPONumber.getEditor() .getEditorComponent()).getText(); if (invoiceVO != null && customerVO != null && !InvoiceBL.isPONumberValid(sPO, invoiceVO.getSubTotal(), customerVO)) { validateComponent = finalizeBaseDialog.cbPONumber; } else if (finalizeBaseDialog.cbDelivery.getSelectedItem().equals( DELIVERY_EMPTY)) { validateComponent = finalizeBaseDialog.cbDelivery; } return validateComponent; } /** * This method place focus on component * * @param componentName * name of the component which needs focus */ protected void placeFocusAfterValidatingPODelivery(String componentName) { if (componentName.equals(FinalizeBaseDialog.CB_PONUMBER)) { finalizeBaseDialog.fldAttention .dispatchEvent(pressTabKey(finalizeBaseDialog.fldAttention)); } else if (componentName.equals("cbDelivery")) { finalizeBaseDialog.cbPONumber .dispatchEvent(pressTabKey(finalizeBaseDialog.cbPONumber)); } } /** * This method replace text if the text to be removed is equal to text * currently displayed * * @param messageCurrentlyDisplayed * Currently displayed text * @param messageNeedsToBeRemoved * Message that needs removal * @return String blank if message to be removed is currently displayed */ protected String returnEmptyStringIfMatched(String messageCurrentlyDisplayed, String messageNeedsToBeRemoved) { return (messageCurrentlyDisplayed != null && messageCurrentlyDisplayed .equals(messageNeedsToBeRemoved)) ? "" : messageCurrentlyDisplayed; } protected KeyEvent pressTabKey(Component source) { return new KeyEvent(source, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, KeyEvent.VK_TAB, '\t'); } protected KeyEvent pressEnterKey(Component source) { logger.debug("=====>> ENTER processPostAndPrintError !!!"); return new KeyEvent(source, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, KeyEvent.VK_ENTER, '\n'); } /** * This method performs localization for properties which are not common * across all controller. Phone room controller has its own * implementation. */ protected void localizeSpecificView() { okText = clientApplicationContext.getResourceBundleReader() .getLocalizedText(ResourceBundleReader.UI, "FinalizeInvoiceDialog.lblOK", clientApplicationContext.getCurrentLocale()); printText = clientApplicationContext.getResourceBundleReader() .getLocalizedText(ResourceBundleReader.UI, "FinalizeInvoiceDialog.btnPrint", clientApplicationContext.getCurrentLocale()); } /** * This method handles the visibility of delivery component. * All four controller implement this method. * @param isEnabled true if needs to enable component * @param handleRadioButtonNo true if needs to handle deliveryNo radio button */ public void enableDeliveryPanel(boolean isEnabled, boolean handleRadioButtonNo) { finalizeBaseDialog.lblDelivery.setEnabled(isEnabled); } /** * This method handles very specific set of component. * Phone room controller has its own implementation. */ protected void enableSpecificPanel() { if(!isBopisInvoice){ finalizeBaseDialog.lblPaymentsTendered.setEnabled(true); finalizeBaseDialog.lblSeqAPLstHdr.setEnabled(true); finalizeBaseDialog.lblTenderLstHdr.setEnabled(true); finalizeBaseDialog.lblAmountLstHdr.setEnabled(true); finalizeBaseDialog.lblPaymentsTendered.setEnabled(true); finalizeBaseDialog.lstPaymentsTendered.setEnabled(true); finalizeBaseDialog.sqfPaymentsTendered.setEnabled(true); finalizeBaseDialog.btnRemove.setEnabled(true); finalizeBaseDialog.lblSequenceNumber.setEnabled(true); finalizeBaseDialog.sqfPaymentsTendered.setText(""); finalizeBaseDialog.sqfPaymentMethod.setText(""); finalizeBaseDialog.lstPaymentMethod.clearSelection(); } } /** * This method handles very specific set of component. * Phone room controller has its own implementation. */ protected void enableSpecificPanel2() { if ((customerVO.getBillTypeCode().equals(RefBillingType.CHARGE_ONLY) && !CustomerBL .isNapaOnlineCustomer(customerVO))|| isBopisInvoice) { finalizeBaseDialog.lblPaymentMethod.setEnabled(false); finalizeBaseDialog.lstPaymentMethod.setEnabled(false); finalizeBaseDialog.lblPaymentMethodSequence.setEnabled(false); finalizeBaseDialog.sqfPaymentMethod.setEnabled(false); } else { finalizeBaseDialog.lblPaymentMethod.setEnabled(true); finalizeBaseDialog.lstPaymentMethod.setEnabled(true); finalizeBaseDialog.lblPaymentMethodSequence.setEnabled(true); finalizeBaseDialog.sqfPaymentMethod.setEnabled(true); } } /** * This method checks for any duplicate payment. Only Optional Checkout controller * has business implementation. Rest three controller use base class implementation. * @param tmpInvVO The InvoiceVO * @return true if any duplicate payment is present */ protected boolean checkAndHandleDuplicatePayments(InvoiceVO tmpInvVO) { boolean redoPmt = false; String keys = null; if (tmpInvVO == null) { keys = invoiceVO.getDuplicatedCardPaymentKeys(); logger.warn("______ read from invoiceVO! keys = " + (keys == null ? "ISNULL" : keys)); } if (keys != null && invoiceVO != null) { // user should have acknowledged with 2204b msg at this point. Void // the dup card trans Vector pmts = invoiceVO.getInvoicePayments(); if (pmts != null && pmts.size() > 0) { for (int m = 0; m < pmts.size(); m++) { if (pmts.get(m) != null && pmts.get(m) instanceof InvoicePaymentVO) { InvoicePaymentVO needToBeVoided = (InvoicePaymentVO) pmts .get(m); if (needToBeVoided.getIpcJournalKey() != null && keys.indexOf(needToBeVoided .getIpcJournalKey()) >= 0) { logger.warn("______ Void duplicated payment: needToBeVoided = " + needToBeVoided.getInfo()); removeDuplicatedIPCPayment(needToBeVoided); } } } } finalizeHandler.setPostAndPrintErrorInvoiceVO(null); finalizeHandler.setPostAndPrintErrorTenderType(null); setCheckoutStatus(); redoPmt = true; } return redoPmt; } /** * This method checks if invoice is from local store. Current Phone room * Checkout controller has business implementation. Rest three controllers * return 'true' as default value. * @return true if invoice is not from phone room. */ protected boolean isInvoiceFromLocalStore() { return true; } /** * This method checks a particular condition . Current Phone room Checkout * controller has business implementation. Rest three controller return * 'true' as default value. * @param returnedInvoiceVO The InvoiceVO * @return true if returnedInvoiceVO is not null. */ protected boolean isProcessAfterPost(InvoiceVO returnedInvoiceVO) { return true; } /** * This method checks whether ipc payment is voided. Optional controller * has its own implementation. Rest all use base class implementation. * @param ipcPayment * @param ipcVoidPaymentSuccess * @return */ protected boolean isPaymentVoided(boolean ipcPmt, Boolean ipcVoidPmtSuccess) { return (ipcPmt && ipcVoidPmtSuccess != null && ipcVoidPmtSuccess .booleanValue()) || ipcVoidPmtSuccess == null; } /** * This method void integrated or Tokenized transaction. Phone room controller * has its own implementation. Rest all use base class implementation.To make * all three controllers to use this method following methods are used so that * all controllers work. * * voidIntegratedTransaction : This method void integrated transaction.Regular * controller has its own implementation. Rest all use base class * implementation. * @param invPaymentVO * @return */ protected int voidIntegratedOrTokenizedTransaction(InvoicePaymentVO invPaymentVO) { int status = DO_NOT_BOTHER; Boolean ipcVoidPmtSuccess = null; if (CreditUtils.isTokenizedPayment(invPaymentVO)) { voidTokenizedTransaction(invPaymentVO); } else if (CreditUtils.isIntegratedPayment(invPaymentVO)) { ipcVoidPmtSuccess = new Boolean( voidIntegratedTransaction(invPaymentVO)); } if (ipcVoidPmtSuccess != null) { if (ipcVoidPmtSuccess.booleanValue()) { status = SUCCESS; } else { status = FAILED; } } return status; } /** * This method check whether optional delivery flag is enabled. * Current Optional controller implement this method. Rest all * use base controller method which return 'false'. * @return */ protected boolean isOptionalDelivery() { return false; } /** * All the key event which are not same in all four controller are moved to * this method. Again Optional controller and Phone room Controller override * this method to their use. * @param ke KeyEvent */ protected void keySpecificReleased(KeyEvent ke) { switch (ke.getKeyCode()) { case KeyEvent.VK_F5: if (finalizeBaseDialog.btnErase.isEnabled()) { if (!isOptionalDelivery()) { finalizeBaseDialog.btnErase.doClick(); } else { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } break; case KeyEvent.VK_F6: if (finalizeBaseDialog.btnExpressCheckout.isEnabled()) { if (!isOptionalDelivery()) { finalizeBaseDialog.btnExpressCheckout.doClick(); } } break; case KeyEvent.VK_F10: if (finalizeBaseDialog.btnSaveInvoice.isEnabled()) { if (!isOptionalDelivery()) { finalizeBaseDialog.btnSaveInvoice.doClick(); } else { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } break; case KeyEvent.VK_F8: if (finalizeBaseDialog.btnVoid.isVisible() && finalizeBaseDialog.btnVoid.isEnabled()) { if (!isOptionalDelivery()) { finalizeBaseDialog.btnVoid.doClick(); } else { finalizeBaseDialog.rbDeliveryNo .dispatchEvent(pressTabKey(finalizeBaseDialog.rbDeliveryNo)); } } break; } } /** * This method checks if the invoice number is present. Current Phone room * controller return default 'true'. Rest all use base class business * implementation. * * @return true if invoice number is present. */ protected boolean isInvoiceNumberPresent() { return invoiceVO != null && invoiceVO.getInvoiceNumber() != null && invoiceVO.getInvoiceNumber().intValue() > 0; } /** * This method performs certain logic before calling remove method.Current * optional controller implement this. Rest all use base class implementation. * @return */ protected boolean processSpecificRemoveCommand(){ boolean isProcessed = true; int selectedListIndex = finalizeBaseDialog.lstPaymentsTendered.getSelectedIndex(); if (selectedListIndex < 0) { isProcessed = false; } else { //Do not allow user remove NAPA Gift Card payment when iPC is in use. final InvoicePaymentVO invPaymentVO = (InvoicePaymentVO) finalizeBaseDialog.lstPaymentsTendered.getSelectedValue(); if (IntegratedPaymentCardHelper.getInstance().isEnabledAndConnected( Profile.POINT_OF_SALE_CLIENT, loc.intValue()) && invPaymentVO.getTenderTypeID().intValue() == RefTenderType.NAPA_GIFT_CARD) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "5062" ); finalizeBaseDialog.cbTax1.dispatchEvent( pressTabKey( finalizeBaseDialog ) ); isProcessed = false; } if (useNapaGCV2() && invPaymentVO.getTenderTypeID().intValue() == RefTenderType.NEW_NAPA_GIFT_CARD && invPaymentVO.isBarcodeBasedGiftCard() && invPaymentVO.getGiftCardTransactionReferenceNum() != null) { if (invPaymentVO.isGiftCardPaymentAlreadyApproved().booleanValue()) { //Calling reload for payment REFUND isProcessed = reloadGiftCardAmount(invPaymentVO, GiftCardConstants.RELOAD_REFUND, null); } else { isProcessed = releaseGiftCardHoldAmount(invPaymentVO); } } } logger.debug("____________________ call removePayment next ... "); return isProcessed; } /** * This method retrieves the delivery priorities. Phone room controller * implement this method to load from remote store. Rest all use base * controller method. * @return * @throws ApplicationException */ protected Vector getDeliveryPriorities() throws ApplicationException{ return clientApplicationContext.getCustomerDAO().getDeliveryPriorityList(loc); } /** * This method checks use tender type flag. Current Phone room * controller implement it to pull data from remote store. * Rest all use base class method. * @return */ protected boolean getUseTenderTypes() { return clientApplicationContext .getProfile(Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()) .getInvoicingProfile().getUseTenderTypes().booleanValue(); } /** * This method returns the dialog name of individual controller. * @return */ protected String getDialogName(){ return finalizeBaseDialog.getName(); } /** * This method prepares a thread. All controller use base class method. * Only phone room has implementation where it perform specific things * before calling base class method. * @return Thread */ protected Thread delegateSetInitialData() { Thread paymentThread = null; if ((bdInvoiceTotal.toString().startsWith("-")) && (CustomerBL.isCashOnDelivery(customerVO))) { escapeKeyPressed = true; paymentThread = new Thread() { public void run() { try { try { join(100); } catch (InterruptedException ee) { logger.debug(ee.getMessage(), ee); } SwingUtilities.invokeAndWait(new Runnable() { public void run() { boolean creditCashOnDelivery = clientApplicationContext .getMessageMgr().showMessageYesNo( finalizeBaseDialog, "2915"); InvoicePaymentVO invoicePaymentVo = new InvoicePaymentVO(); invoicePaymentVo.setLOC(loc); invoicePaymentVo .setAmountTendered(bdInvoiceTotal); logger.debug("=====>> setLOC, setAmountTendered !"); if (creditCashOnDelivery) { invoicePaymentVo .setTenderTypeID(new Byte( (byte) RefTenderType.CHARGE_ON_ACCOUNT)); invoicePaymentVo .setAmountApplied(bdInvoiceTotal); } else { invoicePaymentVo.setTenderTypeID(new Byte( (byte) RefTenderType.CASH)); if (bdInvoiceTotal.compareTo(bdBalanceDue) > 0) { invoicePaymentVo .setAmountApplied(bdBalanceDue); } else { invoicePaymentVo .setAmountApplied(bdInvoiceTotal); } } final InvoicePaymentVO thisPaymentVO = invoicePaymentVo; SwingUtilities.invokeLater(new Thread() { public void run() { logger.debug("=====>> calling pointOfSaleEventDispatcher.firePaymentAdded() !"); pointOfSaleEventDispatcher .firePaymentAdded(new PaymentEvent( this, thisPaymentVO, isDispatchRequired())); } }); } }); } catch (InterruptedException interruptedException) { logger.error(interruptedException.getMessage(), interruptedException); } catch (InvocationTargetException invocationException) { logger.error(invocationException.getMessage(), invocationException); } } }; } boolean isValidAAATransaction = invoiceVO != null && getStoreProfile().getValidateAAAcardnumber().equalsIgnoreCase("Y") && StringUtils.isNotEmpty(invoiceVO.getPONumber()) && CustomerBL.isAAACustomer(customerVO) && InvoiceBL.doesInvoiceContainPurchaseItem(invoiceVO); if (isValidAAATransaction) { logger.debug("Do not load Blanket PO"); } else { loadBlanketPO(); } if (CustomerBL.isNapaOnlineCustomer(customerVO)) { logger.debug("setInitialData for NAPA Online customer"); finalizeBaseDialog.lblErrorMsg.setText(strMustSignReceipt); disablePanel(); /* * We don't want everything disabled that was disabled in the method * disablePanel / so enable the return to invoice button, and check * if we can enable the erase button. / We never want the save * button enabled. */ finalizeBaseDialog.btnRemove.setEnabled(false); finalizeBaseDialog.btnSaveInvoice.setEnabled(false); finalizeBaseDialog.btnReturnToInvoice.setEnabled(true); InvoicePaymentVO invPayVO = new InvoicePaymentVO(); invPayVO.setTenderTypeID(new Byte((byte) RefTenderType.CASH)); invPayVO.setLOC(invoiceVO.getLOC()); getPaymentInfo(invPayVO); invPayVO.setAmountTendered(invoiceVO.getInvoiceTotal()); pointOfSaleEventDispatcher.firePaymentAdded(new PaymentEvent(this, invPayVO)); finalizeBaseDialog.lblPaymentMethod.setEnabled(false); finalizeBaseDialog.lblSequenceNumber.setEnabled(false); finalizeBaseDialog.sqfPaymentsTendered.setEnabled(false); finalizeBaseDialog.btnRemove.setEnabled(false); } if ((customerVO.getBillTypeCode().equals(RefBillingType.CHARGE_ONLY) && !CustomerBL.isNapaOnlineCustomer(customerVO)) && !isBopisInvoice) { skipPaymentMethod = true; InvoicePaymentVO invPayVO = new InvoicePaymentVO(); invPayVO.setTenderTypeID(new Byte( (byte) RefTenderType.CHARGE_ON_ACCOUNT)); invPayVO.setLOC(invoiceVO.getLOC()); invPayVO.setAmountTendered(invoiceVO.getInvoiceTotal()); invPayVO.setAmountApplied(invoiceVO.getInvoiceTotal()); pointOfSaleEventDispatcher.firePaymentAdded(new PaymentEvent(this, invPayVO, isDispatchRequired())); finalizeBaseDialog.lblPaymentMethod.setEnabled(false); // finalizeDialog.cbPaymentMethod.setEnabled(false); finalizeBaseDialog.lblSequenceNumber.setEnabled(false); finalizeBaseDialog.sqfPaymentsTendered.setEnabled(false); finalizeBaseDialog.btnRemove.setEnabled(false); } if (isBopisInvoice) { skipPaymentMethod = true; InvoicePaymentVO invPayVO = new InvoicePaymentVO(); invPayVO.setTenderTypeID(new Byte((byte) RefTenderType.NAPA_ONLINE)); invPayVO.setLOC(invoiceVO.getLOC()); invPayVO.setAmountTendered(invoiceVO.getInvoiceTotal()); invPayVO.setAmountApplied(invoiceVO.getInvoiceTotal()); pointOfSaleEventDispatcher.firePaymentAdded(new PaymentEvent(this, invPayVO, isDispatchRequired())); finalizeBaseDialog.lblPaymentMethod.setEnabled(false); // finalizeDialog.cbPaymentMethod.setEnabled(false); finalizeBaseDialog.lblSequenceNumber.setEnabled(false); finalizeBaseDialog.sqfPaymentsTendered.setEnabled(false); finalizeBaseDialog.btnRemove.setEnabled(false); paymentController.setBalanceDue(invoiceVO.getInvoiceTotal()); Vector vData = new Vector(); finalizeBaseDialog.lstPaymentMethod.setListData(vData); paymentController.displayPaymentPanel(BOPISNAPAONLINEPANEL); } if (invoiceVO.getManualTransaction().booleanValue()) { finalizeBaseDialog.btnSaveInvoice.setEnabled(false); finalizeBaseDialog.cbPrinter.setEnabled(false); } return paymentThread; } /** * Make a private copy of the invoice payments, because there's a * possibility that the framework will clear the data out of the * invoiceListModel object * * @param model * @return */ private Vector copyInvoicePayments(InvoiceListModel model) { if (!validateInvoicePayments(model)) { logger.warn("Copying empty payment list, vanishing invoice payments problem has already occurred."); return new Vector(0); } Vector payments = new Vector(model.size()); for (int i = 0; i < model.size(); i++) { payments.add(model.get(i)); } return payments; } /** * use this to test that the invoice payments are not empty, and log if they * are, so we can track this issue further. * * @param model */ private boolean validateInvoicePayments(InvoiceListModel model) { if (model == null || model.isEmpty()) { logger.warn( "InvoicePayments for this invoice: " + invoiceVO.toString() + " is null/empty, which shouldn't happen at this point", new Exception()); return false; } return true; } /** * This method clear the Attention field. Current phone room controller * has implementation of this method. Rest has empty implementation. */ protected void clearAttention() {} /** * This method set tax table information. Only phone room controller * override this method. Rest all use empty implementation. * @param taxTableVO * @param isPrimary */ protected void setTaxTableOfOriginalInvoiceVO(TaxTableVO taxTableVO, boolean isPrimary){} /** * This method set defaultCustomerTaxId variable. Only Optional controller * implement this method. Rest all use empty implementation. * @param defaultCustomerTaxId */ protected void setDefaultCustomerTaxId(int defaultCustomerTaxId) {} /** * This method performs things after processing print command. Current phone * room controller implement this. Rest all use empty implementation. */ protected void postProcessPrintCommand() {} /** * This method performs things after processing save command. Current phone * room controller implement this. Rest all use empty implementation. */ protected void postProcessSaveCommand() {} public void keyTyped(KeyEvent ke) {} public void windowIconified(WindowEvent we) {} public void windowDeiconified(WindowEvent we) {} public void windowDeactivated(WindowEvent we) {} public void mouseEntered(MouseEvent me) {} public void mouseExited(MouseEvent me) {} public void mousePressed(MouseEvent me) {} public void mouseReleased(MouseEvent me) {} public void invoiceLoaded(InvoiceEvent ie) {} public void windowClosed(WindowEvent we) {} protected void installScreenLockListeners() {} public void customerFieldFocusGained(CustomerEvent ce) {} public void customerFieldValidated(CustomerEvent ce) {} public void invoiceTotalChanged(InvoiceEvent ie) {} /** * This method enable save button. Only phone room controller has its * implementation. Rest all use base class empty implementation. */ protected void enableSaveButton() {} /** * This method set balanceDue in Payment Controller. Only Optional * controller implement this method. Rest all use base class * empty implementation. */ protected void setBalanceDue(){ paymentController.setBalanceDue(bdBalanceDue.negate()); } /** * This method set dialog to PaymentController. Current Regular and * Optional controller is setting dialog. Rest have empty implementation. * @param finalizeBaseDialog */ protected void setCallerDialog(FinalizeBaseDialog finalizeBaseDialog) { paymentController.setCallerDialog(finalizeBaseDialog); } /** * This method checks whether ipc is enabled * @return true if ipc specific operation can be performed. */ protected boolean isIpcEnabled(){ final IntegratedPaymentCardHelper ipcHelper = IntegratedPaymentCardHelper.getInstance(); return ipcHelper.isEnabledAndConnected(Profile.POINT_OF_SALE_CLIENT, loc.intValue()); } /** * This method delegates call to a different method to validate PO and Delivery. * Regular and Optional controller return true. Rest all delegates call to * another method to validate PO and Delivery. * @param placeFocus * @return */ protected abstract boolean validatePODelivery(boolean placeFocus); /** * This method install verifiers for components * which are not common across controller. * @param baseVerifier */ protected abstract void installSpecificVerifiers(FwoBaseInputVerifier baseVerifier); /** * The implementation of this method enable or disable AM PM radio * button. Current Regular and Optional checkout controller has * implementation. Rest has empty implementation. * @param isEnabled true if AMPM needs to be enabled. */ public abstract void resetAMPM(boolean isEnabled); /** * The controllers which have their own way of placing focus override this * method to their use. */ protected abstract void decideSpecificAndPlaceFocus(); /** * This method perform few action on string passed and return it. Current * Regular and Optional has same implementation. Rest return the string * passed. * @param stringTime time in string format * @return String */ protected abstract String prepareTimeToParse(String stringTime); /** * This method determines whether invoice require force post. * @return true if force post is required */ protected boolean isForcePost() { return invoiceVO.isForcePost(); } protected abstract boolean isIthaca(byte printerModel, byte invoiceFormType); protected abstract boolean isPackingCompleted(); protected abstract boolean processPO(); protected abstract boolean processAttention(boolean save); /** * This method logs if payment is empty. This is currently implemented by * Regular and Optional Checkout controller. Both Phone room and Non Phone * Room has empty implementation. * @param payments List of payments selected. */ protected abstract void paymentAndInvoiceListModelConsistencyCheck(Vector payments); /** * This method validates PO. Current Regular and Optional Controller has common * implementation. Phone room and and Non Phone room has common implementation. * * @param placeFocus * @return true if PO is validated successfully. */ protected abstract boolean isPODeliveryValidated(boolean placeFocus); /** * This method set the delivery component for each controller. This is used * since three types of UI component is used for delivery among all * controllers. * @param select true if delivery needs to be selected */ protected abstract void setDelivery(boolean select); /** * This method set optionalDeliveryFlag. Only Optional controller has * implementation. Rest all use empty implementation. * @param set true if flag needs to be enabled. */ protected abstract void setOptionalDelivery(boolean set); /** * This method checks if delivery is applied . All four controllers * implement this method. Phone room and Non Phone room controller * has common implementation. Regular and Optional controller has * individual implementation. * @return true if delivery is selected */ protected abstract boolean isDeliveryChecked(); protected abstract void loadDeliveryComboBasedOnSettings(); /** * This method loads FinalizeHandler. Phone room and Non phone room * controller has specific implementation. Res all use common * implementation. */ protected abstract void loadFinalizeHandler(); protected abstract boolean isDispatchRequired(); /** * This method select AM or PM radio button hour of day. * Current Regular and Optional checkout controller implement this method. * Rest has empty implementation. * @param requestedDeliveryDate Requested delivery Date */ protected abstract void loadDeliveryInfo(Date requestedDeliveryDate); /** * This method checks for payment type. * @param refTableID * @return */ protected boolean isPaymentRelatedToIPC(byte refTableID) { if (useNapaGCV2()) { return refTableID == RefTenderTypeCategory.CREDIT_CARD || refTableID == RefTenderTypeCategory.DEBIT_CARD; } else { return refTableID == RefTenderTypeCategory.CREDIT_CARD || refTableID == RefTenderTypeCategory.DEBIT_CARD || refTableID == RefTenderTypeCategory.NAPA_GIFT_CARD; } } /** * The implementation of this method performs business for optional and * never delivery customer. All controller has their own implementation. * @param priorityID : The delivery priority id. */ protected abstract void loadOptionalNeverDeliveryDefaults(int priorityID); /** * This method set input verifier of AM, PM radio button. Current Regular * and Optional Checkout controller has implementation. Rest has empty * implementation. * @param set boolean variable to set or unset input verifier. */ protected abstract void setSpecificInputVerifier(boolean set); /** * This method is a utility method. Current Regular and Optional Checkout * controller has implementation. Rest has empty implementation. */ protected abstract void handleFldDeliveryTimeFocusLost(); /** * All the focus event which are specific to controller * are moved to this method. Regular and Optional controller has empty * implementation. Phone room and Non Phone room Controller override this * method to their use. * @param fe FocusEvent */ protected abstract void focusSpecificGained(FocusEvent fe); /** * Components which are having different implementation for * getFocusableComponentAfterVerificationis implementing this method to their use. * @param componentName Name of the component. * @param tranferFocusForward true if moving focus forward. * @return */ protected abstract JComponent getSpecificFocusableComponentAfterVerification( String componentName, boolean tranferFocusForward); /* * (non-Javadoc) * * @see * com.gpc.client.common.focusmanager.FocusDecider#getDefaultFocusableComponent * (javax.swing.JComponent, boolean) * Made this as abstract method since all four controllers has significantly * different implementation. */ public abstract JComponent getDefaultFocusableComponent( JComponent currentComponent, boolean tranferFocusForward); /** * The implementation of this method select or deselect AM PM radio * button. Current Regular and Optional checkout controller has * implementation. Rest has empty implementation. */ protected abstract void reSelectAMPM(); /** * This method install listeners for components * which are not common across controller. */ public abstract void installSpecificFocusDeciders(); /** * This method clears components which are * not common across controller. */ protected abstract void resetSpecificPanelData(); /** * This method validates whether time is entered or not. Current Regular * and Optional controller have common implementation. Rest returns * 'true' as default value. * * @param strTemp * @return true if time is empty. */ protected abstract boolean isTimeNotEntered(String strTemp); /** * This method parse time. Current Regular and Optional controller has * similar implementation. Phone room and Non phone room has common * implementation. * * @param strSuffix * @param strTime * @param strTemp * @return java.util.Date */ protected abstract Date processDateToValidate(String strSuffix, String strTime, String strTemp); /** * This method returns specific message id. Current Regular and Optional * controller has similar implementation. Phone room and Non phone room * has common implementation. * * @return message id. */ protected abstract String getMessageId(); /** * This method checks whether a time ends with space. Current Regular and * Optional controller has similar implementation. Phone room and Non * phone room has common implementation. * * @param strSuffix * @param strTime * @return true if time does not end with space. */ protected abstract boolean isTimeRequireSpace(String strSuffix, String strTime); /** * This method checks whether payment card is allowed in payment * method. Only Optional controller has implementation of this * method. Rest all use base class implementation. * @return */ protected boolean isPaymentCardAllowedInPaymentMethod(){ return allowPaymentCardInPaymentMethod() && bdInvoiceSubtotal.compareTo(BD_ZERO) != 0; } /* * When IPC is in use, check if the terminal has a PIN pad attached. If it * does, then allow to add Payment Card entry in the Payment Method list. If * it doesn't and the customer doesn't have card on file, then Payment Card * won't be an option. */ protected boolean allowPaymentCardInPaymentMethod() { if (paymentController.integratedPaymentEnabled) { if (paymentController.isIPCTerminalConnected) { return true; } else if (paymentController.tokenizationEnabled && paymentController.hasCardOnFile(customerVO.getID())) { return true; } } return false; } protected boolean isOfflinePaymentCardPresent(IntegratedPaymentCardHelper ipcHelper) { return true; } /** * This method set Integrated payment variables. */ protected void setIntegratedPaymentVariables(){ paymentController.setIntegratedPaymentVariables(); } /** * This method handles specific mouse click events. Regular controller * has empty implementation. Rest all has their own implementation. * @param source * @param me */ protected abstract void handleSpecificMouseClick(JComponent source, MouseEvent me); /** * This method delegates the napa reward program to a thread */ private Thread delegateToESBRegistration(final Thread paymentThread) { Thread esbThread = null; esbThread = new Thread() { public void run() { /* * This is an existing design used by TAMSII code * to use join when showing dialog on top of dialog. * This will provide enough time for swing to redirect * focus to top window. */ try { join(100); } catch (InterruptedException ee) { logger.debug(ee.getMessage(), ee); } try { SwingUtilities.invokeAndWait(new Runnable() { public void run() { /* * Call is embedded into a Thread as * this call will display dialog on * top of 'Checkout' screen. There is * always a possibility of focus problem * when multiple screen overlap each other. * Call inside thread will almost kill that * possibility. */ handleNapaRewardProgram(paymentThread); } }); } catch (InterruptedException interruptedException) { logger.error(interruptedException.getMessage(), interruptedException); } catch (InvocationTargetException invocationException) { logger.error(invocationException.getMessage(), invocationException); } } }; return esbThread; } /** * Method is used to handle napa reward program. */ private void handleNapaRewardProgram(final Thread paymentThread) { String phoneNumber = ""; String rewardMessage = null; BigDecimal loyaltyEligibleAmount = new BigDecimal("0.00"); StoreProfileVO storeProfile = ApplicationContext.getInstance() .getProfile(Profile.POINT_OF_SALE_CLIENT, loc.intValue()) .getStoreProfile(); final TsoCurrentUser currentUser = clientApplicationContext.getCurrentUser(); String employeeId = currentUser.getEmployeeLdapId(); String correlationId = getCorrelationID(); final LoyaltyRequest loyaltyRequest = new LoyaltyRequest(); loyaltyRequest.setCountryCode(storeProfile.getRefCountryCd()); loyaltyRequest.setCustomerType(LoyaltyConstants.CUSTOMER_TYPE); loyaltyRequest.setInvoiceDate(invoiceVO.getInvoiceDate().toString()); loyaltyRequest.setLanguageCode(storeProfile.getRefLanguageCd()); loyaltyRequest.setPhoneNumber(phoneNumber); loyaltyRequest.setStoreNumber(storeProfile.getStoreNum()); if (isNotEmpty(employeeId)){ loyaltyRequest.setEmployeeUniqueId(employeeId); } else { loyaltyRequest.setEmployeeUniqueId(currentUser.getEmployeeNum().toString()); } loyaltyRequest.setLoyaltyEligibleAmount(loyaltyEligibleAmount); loyaltyRequest.setCorrelationId(correlationId); InvoicingProfileVO invoicingProfileVO = clientApplicationContext .getProfile(Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()).getInvoicingProfile(); final String napaRewardsPromptOption = invoicingProfileVO.getRewardsProgramPrompt(); String savedPhoneNumber = getCustLookupOrVendorIdentifier(LoyaltyConstants.CUSTOMER_LOOKUP); try { loyaltyEligibleAmount = InvoiceBL.calculateLoyaltyEligibleAmount(invoiceVO); loyaltyRequest.setLoyaltyEligibleAmount(loyaltyEligibleAmount); } catch (ApplicationException applicationException) { logger.error(applicationException.getMessage(), applicationException); } int phoneNumberDialogAction = displayPhoneNumberDialog(savedPhoneNumber); if ((phoneNumberDialogAction == PhoneNumberController.DECLINE)) { handleLoyaltyDecline(loyaltyRequest,paymentThread); } else if ((phoneNumberDialogAction == PhoneNumberController.CONTINUE) || (invoiceVO.getLoyaltyCustomerLookup() != null) || (savedPhoneNumber != null) || isNotEmpty(loyaltyCustomerLookup)) { if (isNotEmpty(invoiceVO.getLoyaltyCustomerLookup())) { phoneNumber = invoiceVO.getLoyaltyCustomerLookup(); } else if (isNotEmpty(savedPhoneNumber)) { phoneNumber = savedPhoneNumber; } else if (isNotEmpty(loyaltyCustomerLookup)) { phoneNumber = loyaltyCustomerLookup; } else { phoneNumber = ((PhoneNumberDialog) phoneNumberController .getView()).fldPhoneNumber.getText(); } final String finalPhoneNumber = phoneNumber; loyaltyCustomerLookup = phoneNumber; if (finalPhoneNumber != null ) { loyaltyRequest.setPhoneNumber(finalPhoneNumber); request = loyaltyRequest; final LoyaltyResponse memberStatusResponse = loyaltyProgramService .checkMemberStatus(loyaltyRequest); memberStatusOrDeclineResponse = memberStatusResponse; if ( memberStatusResponse.isSuccess()) { final String firstName = memberStatusResponse.getFirstName(); final String lastName = memberStatusResponse.getLastName(); final String emailAddress = memberStatusResponse.getEmailAddress(); final boolean isCustomerEligibleToUpdateDetails = ((isNullOrEmpty(lastName) || isNullOrEmpty(firstName) || isNullOrEmpty(emailAddress)) && memberStatusResponse.getStatus().equalsIgnoreCase( LoyaltyConstants.ACTIVE) && isNapaRewardsProgramVersion2Active); if (memberStatusResponse.getStatus() .equalsIgnoreCase(LoyaltyConstants.INACTIVE)||isCustomerEligibleToUpdateDetails ) { // New customer new Thread() { public void run() { /* * This is an existing design used by TAMSII code * to use join when showing dialog on top of dialog. * This will provide enough time for swing to redirect * focus to top window. */ try { join(100); } catch (InterruptedException ee) { logger.debug(ee.getMessage(), ee); } try { SwingUtilities.invokeAndWait(new Runnable() { public void run() { /* * Call is embedded into a Thread as * this call will display dialog on * top of 'Checkout' screen. There is * always a possibility of focus problem * when multiple screen overlap each other. * Call inside thread will almost kill that * possibility. */ InvitationDialog invitationDialog = (InvitationDialog) invitationController .getView(); String[] messageParams = new String[] { finalPhoneNumber }; String labelText1 = ParameterizedStringParser .parseString(getLocalizedText(InvitationDialog.DLG_INVITATION + "." + (isCustomerEligibleToUpdateDetails ? InvitationDialog.LBL_INVITATION_UPDATE_MSG1: InvitationDialog.LBL_INVITATION_MSG1)), messageParams); String labelText2 = ParameterizedStringParser .parseString(getLocalizedText(InvitationDialog.DLG_INVITATION + "." + (isCustomerEligibleToUpdateDetails ? InvitationDialog.LBL_INVITATION_UPDATE_MSG2: InvitationDialog.LBL_INVITATION_MSG2)), messageParams); invitationDialog.lblInvitationMsg1.setText(labelText1); invitationDialog.lblInvitationMsg2.setText(labelText2); if(isNapaRewardsProgramVersion2Active) { invitationDialog.fldPhoneNumber.setText(finalPhoneNumber); invitationDialog.fldLastName.setText(lastName); invitationDialog.fldFirstName.setText(firstName); invitationDialog.fldEmailAddress.setText(emailAddress); invitationController.setDoseRewardVersion2Active(true); if(isCustomerEligibleToUpdateDetails) { invitationDialog.btnUpdate.setVisible(true); invitationDialog.btnContinue.setVisible(true); invitationDialog.btnEnroll.setVisible(false); invitationDialog.btnDecline.setVisible(false); } else { invitationDialog.btnUpdate.setVisible(false); invitationDialog.btnContinue.setVisible(false); invitationDialog.btnEnroll.setVisible(true); invitationDialog.btnDecline.setVisible(true); } } if(!isNapaRewardsProgramVersion2Active) { invitationController.invitationDialog.resizeDailogue(); } //Setting this for registration service. invitationController.setLoyaltyRequest(loyaltyRequest); invitationController.setNapaRewardsProgramVersion2Active(isNapaRewardsProgramVersion2Active); int invitationDialogAction = invitationController.show(); if (invitationDialogAction == InvitationController.ENROLL) { final LoyaltyResponse registrationResponse = invitationController.getRegistrationResponse(); if(registrationResponse != null && registrationResponse.isSuccess()){ refLoyaltyCustomerStatusId = new Byte(RefLoyaltyCustomerStatus.ENROLLED); loyaltyCustomerExternalIdentifier = registrationResponse.getVendorRewardMemberIdentifier(); } else { refLoyaltyCustomerStatusId = new Byte(RefLoyaltyCustomerStatus.UNKNOWN); } if (loyaltyRequest.getLoyaltyEligibleAmount() != null && loyaltyRequest.getLoyaltyEligibleAmount().signum() > 0) { processStartTransaction(loyaltyRequest, registrationResponse, finalPhoneNumber, paymentThread); } } else if (invitationDialogAction == InvitationController.DECLINE) { handleLoyaltyDecline(loyaltyRequest,paymentThread); } else if (invitationDialogAction == InvitationController.TRY_AGAIN) { invoiceVO.setLoyaltyCustomerLookup(null); loyaltyCustomerLookup = ""; /* * A recursive call to delegateToESBRegistration. * Once user click on 'Try Again', system should * behave as if screen is loaded for the first * time. This call will take care of all focus * related issues. Since this call display * 'NAPA Rewards Program' dialog, there is no * chance of system going into infinite loop as * system will wait for user input. * */ Thread esbThread = delegateToESBRegistration(paymentThread); if (esbThread != null) { esbThread.start(); } return; } else if(invitationDialogAction == InvitationController.CONTINUE) { continueTransaction(loyaltyRequest, memberStatusResponse, loyaltyRequest.getLoyaltyEligibleAmount(), finalPhoneNumber, paymentThread); } else if(invitationDialogAction == InvitationController.UPDATE) { if(isNapaRewardsProgramVersion2Active) { loyaltyRequest.setLastName(invitationDialog.fldLastName.getText()); loyaltyRequest.setFirstName(invitationDialog.fldFirstName.getText()); loyaltyRequest.setEmailAddress(invitationDialog.fldEmailAddress.getText()); } final LoyaltyResponse memberUpdateResponse = loyaltyProgramService.updateMemberDetails(loyaltyRequest); if(memberUpdateResponse.isSuccess()){ refLoyaltyCustomerStatusId = new Byte(RefLoyaltyCustomerStatus.MEMBER); loyaltyCustomerExternalIdentifier = memberUpdateResponse.getVendorRewardMemberIdentifier(); } else { refLoyaltyCustomerStatusId = new Byte(RefLoyaltyCustomerStatus.UNKNOWN); } if (loyaltyRequest.getLoyaltyEligibleAmount() != null && loyaltyRequest.getLoyaltyEligibleAmount().signum() > 0) { processStartTransaction(loyaltyRequest, memberUpdateResponse, finalPhoneNumber, paymentThread); } } } }); } catch (InterruptedException interruptedException) { logger.error(interruptedException.getMessage(), interruptedException); } catch (InvocationTargetException invocationTargetException) { logger.error(invocationTargetException .getMessage(), invocationTargetException); } } }.start(); } else { continueTransaction(loyaltyRequest, memberStatusResponse, loyaltyEligibleAmount, finalPhoneNumber, paymentThread); } } else { refLoyaltyCustomerStatusId = new Byte(RefLoyaltyCustomerStatus.UNKNOWN); rewardMessage = clientApplicationContext .getResourceBundleReader() .getLocalizedText(ResourceBundleReader.UI, "FinalizeInvoiceDialog.failureMessage", clientApplicationContext.getCurrentLocale()); splitInvoiceNoteLine(invoiceVO.getLineItems(), rewardMessage, LoyaltyConstants.MAX_CHARACTERS_PER_LINE); return; } } } else if (napaRewardsPromptOption.equals(LoyaltyConstants.CUSTOMER_ONLY) && isNullOrEmpty(invoiceVO.getLoyaltyCustomerLookup())) { handleLoyaltyDecline(loyaltyRequest, paymentThread); } } private void continueTransaction(LoyaltyRequest loyaltyRequest, LoyaltyResponse memberStatusResponse, BigDecimal loyaltyEligibleAmount, String finalPhoneNumber, Thread paymentThread) { refLoyaltyCustomerStatusId = new Byte(RefLoyaltyCustomerStatus.MEMBER); loyaltyCustomerExternalIdentifier = memberStatusResponse.getVendorRewardMemberIdentifier(); if (loyaltyEligibleAmount != null && loyaltyEligibleAmount.signum() > 0) { processStartTransaction(loyaltyRequest, memberStatusResponse, finalPhoneNumber, paymentThread); } else if ((loyaltyEligibleAmount != null && loyaltyEligibleAmount.signum() < 0)) { HashSet hashset = new HashSet(); fullInvoiceWithRewardMap = new HashMap(); vendorIdentifierSet = new HashSet(); request = loyaltyRequest; alreadySentLoyaltyAmount = loyaltyEligibleAmount; Vector lineItems = invoiceVO.getLineItems(); if (lineItems != null && lineItems.size() > 0) { for (int i = 0; i < lineItems.size(); i++) { if ((lineItems.get(i) instanceof BaseLineItemVO)) { BaseLineItemVO baseLineItemVO = (BaseLineItemVO) lineItems.get(i); if (baseLineItemVO.getReturnItems() != null) { for (Iterator iterReturnItems = baseLineItemVO.getReturnItems() .iterator(); iterReturnItems.hasNext();) { InvoiceLineItemReturnVO vo = (InvoiceLineItemReturnVO) iterReturnItems .next(); if (vo.getOriginalInvoiceNumber() != null && hashset.add(vo.getOriginalInvoiceNumber())) { isLoyaltyRefund = isFullInvoiceReturnWithReward(vo); invoiceVO.setLoyaltyRefund(isLoyaltyRefund); if (isLoyaltyRefund) { handleLoyaltyRefund(loyaltyRequest, memberStatusResponse, finalPhoneNumber, vo.getOriginalInvoiceNumber(), vo.getLoyaltyInvoiceExternalIdentifier(), paymentThread); } } } } } } } if (fullInvoiceWithRewardMap != null) { invoiceVO.setFullInvoiceWithRewardMap(fullInvoiceWithRewardMap); } if (vendorIdentifierSet != null) { invoiceVO.setVendorIdentifierSet(vendorIdentifierSet); } invoiceLineItemsVector = new Vector(invoiceVO.getLineItems()); } } private String getCorrelationID() { String correlationID = null; logger.debug("invoiceVO.getCorrelationID()>>>"+invoiceVO.getCorrelationID()); if (invoiceVO.getCorrelationID() == null) { StoreProfileVO storeProfile = (invoiceVO!=null && invoiceVO.isPhoneRoomMessagesFlag()) ?(phoneRoomTaapRouter.getStoreProfile(getRemoteIPAddress())) :ApplicationContext.getInstance() .getProfile(Profile.POINT_OF_SALE_CLIENT, loc.intValue()).getStoreProfile(); final TsoCurrentUser currentUser = clientApplicationContext.getCurrentUser(); correlationID = storeProfile.getStoreNum() + currentUser.getEmployeeNum() + System.currentTimeMillis(); invoiceVO.setCorrelationID(correlationID); } else { correlationID = invoiceVO.getCorrelationID(); } return correlationID; } protected void handleLoyaltyMiscAndDelCharges() { if (isNapaRewardProgram) { BigDecimal newLoyaltyEligibleAmt = new BigDecimal("0"); if (request != null){ request.setCorrelationId(getCorrelationID()); try { if(invoiceVO!=null && invoiceVO.isPhoneRoomMessagesFlag()){ newLoyaltyEligibleAmt = PhoneRoomInvoiceBL .calculateLoyaltyEligibleAmount(invoiceVO,getRemoteIPAddress()); }else{ newLoyaltyEligibleAmt = InvoiceBL .calculateLoyaltyEligibleAmount(invoiceVO); } } catch (ApplicationException applicationException) { logger.error(applicationException.getMessage(), applicationException); } if (request != null && memberStatusOrDeclineResponse != null && memberStatusOrDeclineResponse.isSuccess() && newLoyaltyEligibleAmt != null && !alreadySentLoyaltyAmount .equals(newLoyaltyEligibleAmt)) { if (isStartTransactionSuccessful ) { request.setTransactionIdentifier(populateTransactionIdentifierArray()); removeRewardLineItemIfExists(); request.setCorrelationId(getCorrelationID()); if(isNapaRewardsProgramVersion2Active) { request.setLineItems(getLoyaltyEligibleLineItems(invoiceVO)); } LoyaltyResponse cancelResponse = loyaltyProgramService .cancelTransaction(request); if (cancelResponse.isSuccess()) { isStartTransactionSuccessful = false; request.setLoyaltyEligibleAmount(newLoyaltyEligibleAmt); request.setTransactionIdentifier(null); } if (newLoyaltyEligibleAmt.signum() > 0) { processStartTransaction(request, cancelResponse, request.getPhoneNumber(), null); } } else if (invoiceVO.getSubTotal() != null && invoiceVO.getSubTotal().signum() < 0 && newLoyaltyEligibleAmt.signum() > 0) { request.setTransactionIdentifier(null); request.setLoyaltyEligibleAmount(newLoyaltyEligibleAmt); removeRewardLineItemIfExists(); processStartTransaction(request, memberStatusOrDeclineResponse, request.getPhoneNumber(), null); } else if (newLoyaltyEligibleAmt.signum() <= 0){ if (newLoyaltyEligibleAmt.abs().compareTo(rewardForReturn) > 0){ request.setLoyaltyEligibleAmount(newLoyaltyEligibleAmt.add(rewardForReturn)); invoiceVO.setRewardAmount(rewardForReturn.setScale(2, BigDecimal.ROUND_HALF_UP)); finalizeBaseDialog.dlblRewards.setText((rewardForReturn.setScale(2, BigDecimal.ROUND_HALF_UP)).toString()); if (invoiceLineItemsVector != null){ invoiceVO.setLineItems(invoiceLineItemsVector); } if (fullInvoiceWithRewardMap != null) { invoiceVO .setFullInvoiceWithRewardMap(fullInvoiceWithRewardMap); } if (vendorIdentifierSet != null) { invoiceVO .setVendorIdentifierSet(vendorIdentifierSet); } } else { request.setLoyaltyEligibleAmount(newLoyaltyEligibleAmt); invoiceVO.setRewardAmount(BD_ZERO); finalizeBaseDialog.dlblRewards.setText((BD_ZERO.toString())); removeRewardLineItemIfExists(); invoiceVO.setFullInvoiceWithRewardMap(null); invoiceVO.setVendorIdentifierSet(null); } alreadySentLoyaltyAmount = newLoyaltyEligibleAmt; calculateInvoiceTotal(); } } } } } /** * This method is used to handle loyalty decline. */ private void handleLoyaltyDecline(final LoyaltyRequest loyaltyRequest, final Thread paymentThread){ String finalPhoneNumber = ""; loyaltyCustomerLookup = finalPhoneNumber; loyaltyRequest.setPhoneNumber(finalPhoneNumber); request = loyaltyRequest; final LoyaltyResponse declineResponse = loyaltyProgramService .declineRegistration(loyaltyRequest); memberStatusOrDeclineResponse = declineResponse; if (declineResponse.isSuccess()) { refLoyaltyCustomerStatusId = new Byte( RefLoyaltyCustomerStatus.DECLINED); } else { refLoyaltyCustomerStatusId = new Byte( RefLoyaltyCustomerStatus.UNKNOWN); } if (loyaltyRequest.getLoyaltyEligibleAmount() != null && loyaltyRequest.getLoyaltyEligibleAmount().signum() > 0) { processStartTransaction(loyaltyRequest, declineResponse, finalPhoneNumber, paymentThread); } // loyaltyInvoiceExternalIdentifier = null; } /** * This method is used to handle loyalty refund. * @param loyaltyRequest * @param loyaltyResponse * @param phoneNumber * @param fullInvoiceSet * @param invoiceNumber * @param originalVendorIdentifier * @param paymentThread */ private void handleLoyaltyRefund(final LoyaltyRequest loyaltyRequest, final LoyaltyResponse loyaltyResponse, final String phoneNumber, Integer invoiceNumber, String originalVendorIdentifier, final Thread paymentThread) { Vector rewardLineItems = null; if (loyaltyResponse.isSuccess()) { rewardLineItems = loyaltyRefund(loyaltyRequest, invoiceNumber, originalVendorIdentifier); } else { String rewardMessage = clientApplicationContext .getResourceBundleReader().getLocalizedText( ResourceBundleReader.UI, "FinalizeInvoiceDialog.failureMessage", clientApplicationContext.getCurrentLocale()); rewardLineItems = splitInvoiceNoteLine(invoiceVO.getLineItems(), rewardMessage, LoyaltyConstants.MAX_CHARACTERS_PER_LINE); return; } // Adding RWD line and message to invoice. if (rewardLineItems != null && rewardLineItems.size() > 0) { invoiceVO.setLineItems(rewardLineItems); originalInvoiceVo.setLineItems(rewardLineItems); } ((PhoneNumberDialog) phoneNumberController.getView()).fldPhoneNumber.setText(""); invoiceVO.setLoyaltyCustomerLookup(phoneNumber); invoiceVO .setOriginalVendorIdentifier(getCustLookupOrVendorIdentifier(LoyaltyConstants.VENDOR_IDENTIFIER)); if (paymentThread != null) { paymentThread.start(); } } /** * This method is used to create reward line item for refund. * @param originalVendorIdentifier * @param invoiceNumber */ private Vector loyaltyRefund(LoyaltyRequest loyaltyRequest, Integer invoiceNumber, String originalVendorIdentifier) { BigDecimal reward = invoiceVO.getRewardLineItemUnitPrice(); Vector lineItems = invoiceVO.getLineItems(); loyaltyInvoiceExternalIdentifier = null; BaseLineItemVO bliVO = null; if (reward != null && reward.intValue() != 0) { if (loyaltyRequest.getLoyaltyEligibleAmount() != null && loyaltyRequest.getLoyaltyEligibleAmount().abs() .compareTo(reward) > 0) { bliVO = InvoiceLineBL.createLineItemForRewards(invoiceVO, customerVO, reward, new BigDecimal("1.00")); bliVO.setLoyaltyEligible( isLineItemEligibleForNapaRewards(bliVO.getRefInvoiceLineItemTypeID())); lineItems.add(bliVO); reward = reward.add(invoiceVO.getRewardAmount()); rewardForReturn = reward; loyaltyRequest.setLoyaltyEligibleAmount(loyaltyRequest .getLoyaltyEligibleAmount().add(rewardForReturn)); invoiceVO.setRewardAmount(reward.setScale(2, BigDecimal.ROUND_HALF_UP)); finalizeBaseDialog.dlblRewards.setText((reward.setScale(2, BigDecimal.ROUND_HALF_UP)).toString()); fullInvoiceWithRewardMap.put(invoiceNumber, invoiceVO.getRewardLineItemUnitPrice()); vendorIdentifierSet.add(originalVendorIdentifier); } else { invoiceVO.setRewardAmount(BD_ZERO); finalizeBaseDialog.dlblRewards.setText((BD_ZERO.toString())); invoiceVO.setRewardLineItemUnitPrice(BD_ZERO); } calculateInvoiceTotal(); modifyTaxDecisionForRewardLine(bliVO); } /*String refundMessage = clientApplicationContext .getResourceBundleReader().getLocalizedText( ResourceBundleReader.UI, "FinalizeInvoiceDialog.refundMessage", clientApplicationContext.getCurrentLocale()); payPanel.taRewardMessage.setText(refundMessage); payPanel.taRewardMessage.setVisible(true);*/ request = loyaltyRequest; return lineItems; } /** * This method checks if the return is a full invoice return and has a NAPA reward line item. * @param invoiceLineItemReturnVO */ private boolean isFullInvoiceReturnWithReward(InvoiceLineItemReturnVO invoiceLineItemReturnVO) { invoiceReturnItemsList = new ArrayList(); Vector lineItems = invoiceVO.getLineItems(); if (!isInvoiceContainsRewardline(invoiceLineItemReturnVO)) { return false; } if (lineItems != null && lineItems.size() > 0) { for (int i = 0; i < lineItems.size(); i++) { if ((lineItems.get(i) instanceof BaseLineItemVO)) { BaseLineItemVO baseLineItemVO = (BaseLineItemVO) lineItems.get(i); if (baseLineItemVO.getReturnItems() != null) { boolean firstElement = true; for (Iterator iterReturnItems = baseLineItemVO .getReturnItems().iterator(); iterReturnItems .hasNext();) { if (napaRewardsNonEligibleList != null && !napaRewardsNonEligibleList .contains(baseLineItemVO .getRefInvoiceLineItemTypeID())) { InvoiceLineItemReturnVO vo = (InvoiceLineItemReturnVO) iterReturnItems .next(); if (invoiceLineItemReturnVO.getOriginalInvoiceNumber().equals(vo.getOriginalInvoiceNumber())){ if(firstElement){ firstElement = false; if(vo.getHasMiscCharge() != null && vo.getHasMiscCharge().booleanValue()){ Vector miscCharges = vo.getMiscCharge(); if(miscCharges != null){ for(int index = 0; index < miscCharges.size(); index++){ Object miscCharge = miscCharges.get(index); if(miscCharge instanceof BaseLineItemVO){ BaseLineItemVO miscChargeVO = (BaseLineItemVO)miscCharge; if(isLineItemEligibleForNapaRewards( CommonInvoiceLineBL.getLineItemType( miscChargeVO, customerVO))){ addToInvoiceReturnItemsList(miscChargeVO, vo); } } } } } } addToInvoiceReturnItemsList(baseLineItemVO, vo); } } } } } } } if (invoiceLineItemReturnVO != null && invoiceLineItemReturnVO.getOriginalInvoiceNumber() != null) { invoiceVO.setOriginalInvoiceNumber(invoiceLineItemReturnVO .getOriginalInvoiceNumber().toString()); } return isFullInvoiceReturn(); } /** * This code added to fix issue of not reversing reward when an invoice is splitted. * e.g. If an invoice contain line 1/AC with quantity 2. Now return is made in one * invoice by splitting invoice as 1/AC with quantity -1 and 1/AC with quantity -1. * @param baseLineItemVO * @param invoiceLineItemReturnVO */ private void addToInvoiceReturnItemsList(BaseLineItemVO baseLineItemVO, InvoiceLineItemReturnVO invoiceLineItemReturnVO){ CustomReturnInfo customReturnInfo = findAlreadyAddedLine(baseLineItemVO .getLineAbbr(), baseLineItemVO.getPartNum(), invoiceLineItemReturnVO); CustomInvoiceLineItemVO invoiceLineItemVO = new CustomInvoiceLineItemVO( baseLineItemVO.getLineAbbr(), baseLineItemVO.getPartNum(), invoiceLineItemReturnVO.getQtyReturned() .add(invoiceLineItemReturnVO.getDisplayQuantityReturned())); if(customReturnInfo != null && customReturnInfo.index != -1){ invoiceReturnItemsList.set(customReturnInfo.index, invoiceLineItemVO); } else { boolean added = invoiceReturnItemsList.add(invoiceLineItemVO); if(added){ returnHistory.put(customReturnInfo , new Integer(invoiceReturnItemsList.size() - 1)); } } } /** * This method look for any particular line which is generated from same invoice * for more than one occurance. * * @param line * @param part * @param vo * @return */ private CustomReturnInfo findAlreadyAddedLine(String line, String part, InvoiceLineItemReturnVO vo) { CustomReturnInfo customReturnInfo = null; if(vo.getOriginalInvoiceLineItemSequence() != null){ CustomReturnInfo newCustomReturnInfo = new CustomReturnInfo(line, part, vo.getOriginalInvoiceLineItemSequence().shortValue(), vo.getOriginalInvoiceNumber().intValue()); Integer alreadyAddedLineItemIndex = (Integer)returnHistory.get(newCustomReturnInfo); int index = -1; if(alreadyAddedLineItemIndex != null){ index = alreadyAddedLineItemIndex.intValue(); } newCustomReturnInfo.index = index; customReturnInfo = newCustomReturnInfo; } return customReturnInfo; } /** * This method compares the two ArrayList, one containing the return items from the invoicing screen * and the other one with the original invoice line items for the same invoice number from the TAMSII database. * @return Returns true if both the list items are identical. */ private boolean isFullInvoiceReturn() { if (invoiceReturnItemsList != null && originalInvoiceLineItemsList != null && invoiceReturnItemsList.size() > 0 && originalInvoiceLineItemsList.size() > 0) { if (invoiceReturnItemsList.size() != originalInvoiceLineItemsList.size()){ return false; } for (int index = 0; index < invoiceReturnItemsList.size(); index++) { if (!originalInvoiceLineItemsList.contains(invoiceReturnItemsList .get(index))) { return false; } } } else { return false; } return true; } /** * This method checks if the invoice contains NAPA reward line item. * @return Returns true if the invoice contains NAPA reward line item. */ private boolean isInvoiceContainsRewardline( InvoiceLineItemReturnVO invoiceLineItemReturnVO) { boolean isInvoiceContainsRewardline = false; InvoiceVO invoice = getInvoice(invoiceLineItemReturnVO); BigDecimal reward = new BigDecimal("0"); originalInvoiceLineItemsList = new ArrayList(); returnHistory = new HashMap(); if (invoice != null) { Vector vInvoiceLines = invoice.getLineItems(); for (int i = 0; i < vInvoiceLines.size(); i++) { InvoiceLineItemVO invoiceLineItemVO = (InvoiceLineItemVO) vInvoiceLines .elementAt(i); if (invoiceLineItemVO instanceof BaseLineItemVO) { BaseLineItemVO baseLineItemVO = (BaseLineItemVO) invoiceLineItemVO; if (baseLineItemVO.getRefInvoiceLineItemTypeID().intValue() == RefInvoiceLineItemType.NAPA_REWARDS) { isInvoiceContainsRewardline = true; reward = invoiceLineItemVO.getUnitPrice() != null ? invoiceLineItemVO .getUnitPrice().abs() : new BigDecimal("0"); invoiceVO.setRewardLineItemUnitPrice(reward.setScale(2, BigDecimal.ROUND_HALF_UP)); } else { if(baseLineItemVO.isKitPart() && baseLineItemVO.getGeneratedBySequence() != null){ continue; } if (napaRewardsNonEligibleList!=null && !napaRewardsNonEligibleList.contains(baseLineItemVO .getRefInvoiceLineItemTypeID())){ CustomInvoiceLineItemVO invoiceLineItem = new CustomInvoiceLineItemVO( baseLineItemVO.getLineAbbr(), baseLineItemVO.getPartNum(), baseLineItemVO.getQuantityBilled()); originalInvoiceLineItemsList.add(invoiceLineItem); } } } } } return isInvoiceContainsRewardline; } private boolean isLineItemEligibleForNapaRewards(Byte refInvoiceLineItemTypeId){ return napaRewardsNonEligibleList!=null && !napaRewardsNonEligibleList.contains(refInvoiceLineItemTypeId); } /** * This method gets the invoice details based in the invoice id. * @param LoyaltyRequest. * @return Returns InvoiceVO. */ private InvoiceVO getInvoice(InvoiceLineItemReturnVO invoiceLineItemReturnVO) { ClientApplicationContext clientApplicationContext = ClientApplicationContext .getClientApplicationContext(); InvoiceVO invoiceVO = null; try { if (invoiceLineItemReturnVO != null) { invoiceVO = clientApplicationContext.getInvoiceDAO() .findInvoice(invoiceLineItemReturnVO.getInvoiceID(), invoiceLineItemReturnVO.getLOC()); } } catch (ApplicationException applicationException) { logger.error(applicationException.getMessage(), applicationException); } return invoiceVO; } /** * This method calls the startTransaction method and sets the modified line items to the invoiceVO . * @param LoyaltyRequest. * @param loyaltyResponse. * @param phoneNumber. * @param paymentThread. */ private void processStartTransaction(final LoyaltyRequest loyaltyRequest, final LoyaltyResponse loyaltyResponse, final String phoneNumber, final Thread paymentThread){ Vector rewardLineItems = null; if (loyaltyResponse != null && loyaltyResponse.isSuccess()) { rewardLineItems = startTransaction(loyaltyRequest); } else { String rewardMessage = clientApplicationContext .getResourceBundleReader().getLocalizedText( ResourceBundleReader.UI, "FinalizeInvoiceDialog.failureMessage", clientApplicationContext.getCurrentLocale()); rewardLineItems = splitInvoiceNoteLine(invoiceVO.getLineItems(), rewardMessage, LoyaltyConstants.MAX_CHARACTERS_PER_LINE); return; } // Adding RWD line and message to invoice. if (rewardLineItems != null && rewardLineItems.size() > 0) { invoiceVO.setLineItems(rewardLineItems); originalInvoiceVo.setLineItems(rewardLineItems); } ((PhoneNumberDialog) phoneNumberController.getView()).fldPhoneNumber.setText(""); invoiceVO.setLoyaltyCustomerLookup(phoneNumber); if (loyaltyRequest != null && loyaltyRequest.getLoyaltyEligibleAmount() != null && loyaltyRequest.getLoyaltyEligibleAmount().signum() < 0) { request.setTransactionIdentifier(populateTransactionIdentifierArray()); if(isNapaRewardsProgramVersion2Active) { request.setLineItems(getLoyaltyEligibleLineItems(invoiceVO)); } loyaltyProgramService.cancelTransaction(loyaltyRequest); } if (paymentThread != null) { paymentThread.start(); } } /** * This method updates the loyalty_eligible value for every line item * @param loyaltyRequest */ private void updateLoyaltyEligibleForLineItem() { Vector vInvoiceLines = invoiceVO.getLineItems(); if (vInvoiceLines != null) { for (int i = 0; i < vInvoiceLines.size(); i++) { InvoiceLineItemVO invoiceLineItemVO = (InvoiceLineItemVO) vInvoiceLines .elementAt(i); if (invoiceLineItemVO instanceof BaseLineItemVO) { BaseLineItemVO baseLineItemVO = (BaseLineItemVO) invoiceLineItemVO; if (napaRewardsNonEligibleList != null && napaRewardsNonEligibleList .contains(baseLineItemVO .getRefInvoiceLineItemTypeID())) { baseLineItemVO.setLoyaltyEligible(false); } else { baseLineItemVO.setLoyaltyEligible(true); } } } } } /** * This method calls the start transaction of loyaltyProgramService and * gets the reward from the loyaltyResponse object and creates the reward line item. * @param loyaltyRequest */ private Vector startTransaction(LoyaltyRequest loyaltyRequest) { loyaltyRequest.setCorrelationId(getCorrelationID()); if(isNapaRewardsProgramVersion2Active) { loyaltyRequest.setLineItems(getLoyaltyEligibleLineItems(invoiceVO)); } LoyaltyResponse loyaltyResponse = loyaltyProgramService .startTransaction(loyaltyRequest); String rewardMessage = null; BigDecimal reward = new BigDecimal("0.00"); BaseLineItemVO bliVO = new BaseLineItemVO(); Vector lineItems = invoiceVO.getLineItems(); if (loyaltyResponse.isSuccess()) { alreadySentLoyaltyAmount = loyaltyRequest.getLoyaltyEligibleAmount(); loyaltyInvoiceExternalIdentifier = loyaltyResponse.getVendorTransactionIdentifier(); reward = getReward(loyaltyResponse, loyaltyRequest.getLoyaltyEligibleAmount()); if (reward != null && reward.intValue() != 0) { bliVO = InvoiceLineBL.createLineItemForRewards(invoiceVO, customerVO, reward.abs(), new BigDecimal("-1.00")); if (napaRewardsNonEligibleList != null && napaRewardsNonEligibleList.contains(bliVO .getRefInvoiceLineItemTypeID())) { bliVO.setLoyaltyEligible(false); } else { bliVO.setLoyaltyEligible(true); } lineItems.add(bliVO); } invoiceVO.setRewardAmount(reward); finalizeBaseDialog.dlblRewards.setText((reward.setScale(2, BigDecimal.ROUND_HALF_UP)).toString()); calculateInvoiceTotal(); lineItems = createNAPARewardMessage(loyaltyResponse, lineItems); modifyTaxDecisionForRewardLine(bliVO); isStartTransactionSuccessful = true; request = loyaltyRequest; } else { rewardMessage = clientApplicationContext.getResourceBundleReader() .getLocalizedText(ResourceBundleReader.UI, "FinalizeInvoiceDialog.failureMessage", clientApplicationContext.getCurrentLocale()); lineItems = splitInvoiceNoteLine(lineItems, rewardMessage, LoyaltyConstants.MAX_CHARACTERS_PER_LINE); } return lineItems; } /** * This method will turn off the tax decision for NAPA Rewards line if * absolute value of the rest of the invoice tax calculated is less than * absolute value of the reward tax calculated. This is done to avoid * receiving a tax credit for a tax exempt customer i.e.,to fix the * issue #TII-19393. * * @param bliVO */ private void modifyTaxDecisionForRewardLine(BaseLineItemVO bliVO) { boolean isTaxDecisionModified = false; if (bliVO != null && (bliVO.getTaxable1().booleanValue() || bliVO .getTaxable2().booleanValue())) { if (bliVO.getTaxable1().booleanValue()) { if (invoiceVO.getTaxableSales1() != null && bliVO.getExtendedPrice() != null && (invoiceVO.getTaxableSales1().subtract(bliVO .getExtendedPrice())).abs().compareTo( bliVO.getExtendedPrice().abs()) < 0) { bliVO.setTaxable1(Boolean.FALSE); isTaxDecisionModified = true; } } if (bliVO.getTaxable2().booleanValue()) { if (invoiceVO.getTaxableSales2() != null && bliVO.getExtendedPrice() != null && (invoiceVO.getTaxableSales2() .subtract(bliVO.getExtendedPrice()).abs() .compareTo(bliVO.getExtendedPrice().abs()) < 0)) { bliVO.setTaxable2(Boolean.FALSE); isTaxDecisionModified = true; } } if (isTaxDecisionModified) { calculateInvoiceTotal(); } } } /** * This method calculates the reward from the loyaltyResponse object * @param loyaltyResponse * @param loyaltyEligibleAmount */ private BigDecimal getReward(LoyaltyResponse loyaltyResponse,BigDecimal loyaltyEligibleAmount) { BigDecimal Reward = loyaltyResponse.getCalculatedTransactionAmount() .subtract(loyaltyEligibleAmount); Reward = Reward.setScale(2, BigDecimal.ROUND_HALF_UP); return Reward; } /** * This method creates the NAPA reward message as invoice note * and displays the message in PaymentPanel. * @param loyaltyResponse * @param lineItems */ private Vector createNAPARewardMessage(LoyaltyResponse loyaltyResponse, Vector lineItems) { Message[] messageArray = loyaltyResponse.getMessage(); StringBuffer receiptMessageBuffer = new StringBuffer(); if (messageArray != null) { for (int index = 0; index < messageArray.length; index++) { com.gpc.valueobjects.loyalty.Message message = messageArray[index]; if (message != null && message.getMessage() !=null) { if (message.getMessageType().equalsIgnoreCase( LoyaltyConstants.RECEIPT_TEXT) ) { receiptMessageBuffer.append(message.getMessage()); lineItems = splitInvoiceNoteLine(lineItems, message.getMessage(), LoyaltyConstants.MAX_CHARACTERS_PER_LINE); receiptMessageBuffer.append("\n"); } } else { payPanel.taRewardMessage.setVisible(false); } } } else { payPanel.taRewardMessage.setVisible(false); } if (!receiptMessageBuffer.toString().equalsIgnoreCase("")) { payPanel.taRewardMessage.setText(receiptMessageBuffer.toString()); payPanel.taRewardMessage.setVisible(true); } return lineItems; } /** * This method displays the phone number dialog * @param loyaltyCustomerLookup */ private int displayPhoneNumberDialog(String phoneNumber) { int phoneNumberDialogAction = 0; InvoicingProfileVO invoicingProfileVO = clientApplicationContext .getProfile(Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()).getInvoicingProfile(); final String napaRewardsPromptOption = invoicingProfileVO.getRewardsProgramPrompt(); if (napaRewardsPromptOption.equals(LoyaltyConstants.CUSTOMER_ONLY)) { return phoneNumberDialogAction; } if ((isNullOrEmpty(invoiceVO.getLoyaltyCustomerLookup())) && (isNullOrEmpty(phoneNumber))) { if (isNullOrEmpty(loyaltyCustomerLookup)){ phoneNumberDialogAction = phoneNumberController.show(); } } return phoneNumberDialogAction; } /** * This method returns true if the string value is null or empty * @param String value */ private boolean isNullOrEmpty(String value){ return (value == null || value.trim().equals("")); } /** * This method returns true if the string value is not an empty string * @param String value */ private boolean isNotEmpty(String value){ return (value != null && !value.trim().equals("")); } /** * Method is used to split the invoice note line description to separate lines when the * length exceeds maximum line width * * @param invoiceNote is the note description * * @param maxLineWidth is the maximum number of characters allowed in a line. * * @return a vector containing invoice note line description. */ private static Vector splitInvoiceNoteLine(final Vector lineItems, final String invoiceNote, final int maxLineWidth) { final List invoiceNoteList = new ArrayList(); int startIndex = 0; int endIndex = maxLineWidth; if (invoiceNote != null) { if (invoiceNote.length() >= endIndex) { do { while (invoiceNote.charAt(endIndex) != ' ' && endIndex > startIndex) { endIndex--; } if (endIndex == startIndex) { endIndex = startIndex + maxLineWidth; } invoiceNoteList.add(invoiceNote.substring(startIndex, endIndex).trim()); startIndex = endIndex; endIndex += maxLineWidth; } while (endIndex < invoiceNote.length()); } invoiceNoteList.add(invoiceNote.substring(startIndex).trim()); } for (int index = 0; index < invoiceNoteList.size(); index++) { InvoiceNoteVO invNote = new InvoiceNoteVO(); String noteLineDesc = (String) invoiceNoteList.get(index); invNote.setRefInvoiceNoteTyepID(new Integer( RefInvoiceNoteType.NAPA_REWARD_PROGRAM)); invNote.setText(noteLineDesc); invNote.setGeneratedByLineItem(null); invNote.setCompletedLine(true); lineItems.add(invNote); } return lineItems; } /** * This method removes the Reward line item and reward note if exists in the invoice */ protected void removeRewardLineItemIfExists() { List itemList = invoiceVO.getLineItems(); List deleteItems = new ArrayList(); if (itemList != null) { InvoiceLineItemVO lineItem = null; for (int index = 0; index < itemList.size(); index++) { lineItem = (InvoiceLineItemVO) itemList.get(index); if ((lineItem instanceof InvoiceNoteVO && (((InvoiceNoteVO) lineItem) .getRefInvoiceNoteTyepID().intValue() == RefInvoiceNoteType.NAPA_REWARD_PROGRAM)) || (lineItem.getLineAbbr().equalsIgnoreCase( LoyaltyConstants.REWARD_LINE) && lineItem .getPartNum().equalsIgnoreCase( LoyaltyConstants.REWARD_PART))) { deleteItems.add(lineItem); } } } if (deleteItems.size() > 0) { itemList.removeAll(deleteItems); } } /** * This method returns LoyaltyCustomerLookup of a returned line item */ private String getCustLookupOrVendorIdentifier(String parameter) { Vector lineItems = invoiceVO.getLineItems(); if (lineItems != null && lineItems.size() > 0) { for (int i = 0; i < lineItems.size(); i++) { if ((lineItems.get(i) instanceof BaseLineItemVO)) { BaseLineItemVO baseLineItemVO = (BaseLineItemVO) lineItems .get(i); if (baseLineItemVO.getReturnItems() != null) { for (Iterator iterReturnItems = baseLineItemVO .getReturnItems().iterator(); iterReturnItems .hasNext();) { InvoiceLineItemReturnVO vo = (InvoiceLineItemReturnVO) iterReturnItems .next(); if (parameter .equalsIgnoreCase(LoyaltyConstants.CUSTOMER_LOOKUP)) { if (vo.getLoyaltyCustomerLookup() != null){ return vo.getLoyaltyCustomerLookup(); } } else if (parameter .equalsIgnoreCase(LoyaltyConstants.VENDOR_IDENTIFIER)) { return vo.getLoyaltyInvoiceExternalIdentifier(); } } } } } } return null; } /** * This class acts as key to track line generated from return invoice. * */ private static class CustomReturnInfo{ private String line; private String part; private short originalSequence; private int originalInvoiceNumber; private int index; CustomReturnInfo(String line, String part, short originalSequence, int originalInvoiceNumber) { this.line = line; this.part = part; this.originalSequence = originalSequence; this.originalInvoiceNumber = originalInvoiceNumber; } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((line == null) ? 0 : line.hashCode()); result = prime * result + originalInvoiceNumber; result = prime * result + originalSequence; result = prime * result + ((part == null) ? 0 : part.hashCode()); return result; } public boolean equals(Object obj) { if (this == obj){ return true; } if (obj == null){ return false; } if (getClass() != obj.getClass()){ return false; } CustomReturnInfo other = (CustomReturnInfo) obj; if (line == null) { if (other.line != null){ return false; } } else if (!line.equals(other.line)){ return false; } if (originalInvoiceNumber != other.originalInvoiceNumber){ return false; } if (originalSequence != other.originalSequence){ return false; } if (part == null) { if (other.part != null){ return false; } } else if (!part.equals(other.part)){ return false; } return true; } } /** * This class is created to track uniqueness of line items so that * elements between return and purchase can be compared easily. */ private static class CustomInvoiceLineItemVO{ private String line; private String part; private BigDecimal quantity; public CustomInvoiceLineItemVO(String line, String part, BigDecimal quantity) { this.line = line; this.part = part; this.quantity = quantity; } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((line == null) ? 0 : line.hashCode()); result = prime * result + ((part == null) ? 0 : part.hashCode()); result = prime * result + ((quantity == null) ? 0 : quantity.intValue()); return result; } public boolean equals(Object obj) { if (this == obj){ return true; } if (obj == null){ return false; } if (getClass() != obj.getClass()){ return false; } CustomInvoiceLineItemVO other = (CustomInvoiceLineItemVO) obj; if (line == null) { if (other.line != null){ return false; } } else if (!line.equals(other.line)){ return false; } if (part == null) { if (other.part != null){ return false; } } else if (!part.equals(other.part)){ return false; } if (quantity == null) { if (other.quantity != null){ return false; } } else if(other.quantity == null){ return false; } else if (!quantity.abs().equals(other.quantity.abs())){ return false; } return true; } } private boolean askForCustomerRFC() { boolean askForCustomerRFC= false; if (!CustomerBL.isTransferCustomer(customerVO) && (customerVO.getCustomerNumber().intValue() == 0 || customerVO.getTaxExemptNumberPrimary() == null || customerVO.getTaxExemptNumberPrimary().trim().length() <= 0 )) { askForCustomerRFC =true; } return askForCustomerRFC; } private void displayCustomerInfoModal(boolean displayStampAgian, InvoiceVO invVO) { customerInfoController.setInitialData(invVO, customerVO); if (displayStampAgian) { customerInfoController.customerInfoDialog.btnStampAgain.setVisible(displayStampAgian); customerInfoController.customerInfoDialog.btnStampAgain.setEnabled(displayStampAgian); customerInfoController.customerInfoDialog.btnOk.setVisible(false); customerInfoController.customerInfoDialog.btnOk.setEnabled(false); } else { customerInfoController.customerInfoDialog.btnOk.setVisible(true); customerInfoController.customerInfoDialog.btnOk.setEnabled(true); customerInfoController.customerInfoDialog.btnStampAgain.setVisible(false); customerInfoController.customerInfoDialog.btnStampAgain.setEnabled(false); } customerInfoController.show(); customerInfoController.customerInfoDialog.fldRFCNumber.requestFocus(); } private void displayTransportInfoModal(TransportInvoiceInfoVO transportVO) { transportInfoController = new TransportInvoiceInfoController(finalizeBaseDialog); transportInfoController.setInitialData(transportVO); transportInfoController.transportInfoDialog.btnEnter.setVisible(true); transportInfoController.transportInfoDialog.btnEnter.setEnabled(true); transportInfoController.setModel(transportVO); transportInfoController.setViewVisible(true); } private void displayCustomerInfoModalforNextAttempt(InvoiceVO returnedInvoiceVO) { logger.debug("[EInvoice] FinalizeInvoiceBaseController.displayCustomerInfoModalforNextAttempt - " + "R.F.C = " + returnedInvoiceVO.getRfcNumber() + ", Name = " + returnedInvoiceVO.getCFDIName() + ", Postal Code = " + returnedInvoiceVO.getCFDIPostalCode()); CEPDIStatusVO cepdiStatusVO = null; try { for (int index = 0; MAXIMUM_ATTEMPTS > index; index++) { displayCustomerInfoModal(true, returnedInvoiceVO); logger.debug("displayCustomerInfoModalforNextAttempt - Enetered RFC Number = " + returnedInvoiceVO.getRfcNumber()); if (StringUtils.isNotEmpty(returnedInvoiceVO.getRfcNumber()) && StringUtils.isNotEmpty(returnedInvoiceVO.getCFDIName()) && StringUtils.isNotEmpty(returnedInvoiceVO.getCFDIPostalCode())) { cepdiStatusVO = clientApplicationContext.getInvoiceDAO().stampEInvoice( returnedInvoiceVO); logger.debug(" Response for the Attempt number - " + index + " is = \n" + cepdiStatusVO); } else { break; } if (cepdiStatusVO != null && cepdiStatusVO.getStatus().equalsIgnoreCase("true")) { clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "10104"); break; } else if (cepdiStatusVO.getErrorCode() != null && cepdiStatusVO.getErrorMessage() != null && (isInvalidCustomerRFC(cepdiStatusVO) || isInValidCustomerPostalCode(cepdiStatusVO) || isInValidCustomerName(cepdiStatusVO))) { // Invalid R.F.C if(isInvalidCustomerRFC(cepdiStatusVO)) { if (index == 0) { clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "10111", new String[] {cepdiStatusVO.getErrorMessage(), "1"}); } else { clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "10112"); } } else if(isInValidCustomerName(cepdiStatusVO)) { if (index == 0) { clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "10501", new String[] {cepdiStatusVO.getErrorMessage(), "1"}); } else { clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "10503"); } } else if (isInValidCustomerPostalCode(cepdiStatusVO)) { if(index == 0) { clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "10502", new String[] {cepdiStatusVO.getErrorMessage(), "1"}); } else { clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "10504"); } } } else { clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "10110", new String[] { cepdiStatusVO.getErrorMessage() }); break; } } } catch (ApplicationException applicationException) { logger.error(applicationException.toString(), applicationException); clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "10110", new String[] { "Exception occured while sending invoice info to CEPDI service" }); } } /** * Method used to correct amount differences (cents) between Sales ticket and Stamped Invoice. * * @param {@link InvoiceVO} value object contains Invoice information. * * @param {@link CustomerVO} value object contains Customer information. */ protected void reCalculateInvoiceTaxAmount(final InvoiceVO invoiceVO, final CustomerVO customerVO) { final String methodSpec = "FinalizeInvoiceBaseController.reCalculateInvoiceTaxAmount - "; logger.debug(methodSpec); final StoreProfileVO storeProfileVO = ApplicationContext.getInstance() .getProfile(Profile.POINT_OF_SALE_CLIENT, loc.intValue()).getStoreProfile(); InvoiceBL.reCalculateInvoiceTaxAmount(invoiceVO, customerVO, storeProfileVO); } /** * Method to check whether to correct invoice amount differences (cents) between sales ticket * and stamped invoice * * @param {@link InvoiceVO} value object contains invoice information. * * @param {@link CustomerVO} value object contains Customer details * * @return boolean value to indicate whether invoice amount corrections should be applied * or not. */ protected boolean doesInvoiceTaxAmountCorrectionRequired(final InvoiceVO invoiceVO, final CustomerVO customerVO) { final String methodSpec = "FinalizeInvoiceBaseController.doesInvoiceTaxAmountCorrectionsRequired - "; logger.debug(methodSpec); boolean invoiceAmountCorrectionsRequired = true; if (CustomerBL.isTransferCustomer(customerVO) || isDeliveryChargeApplicable() || isMiscChargeApplicable() || doesInvoiceContainSecondaryTaxAmount(invoiceVO)) { invoiceAmountCorrectionsRequired = false; } logger.debug(methodSpec + "InvoiceAmountCorrectionsRequired = " + invoiceAmountCorrectionsRequired); return invoiceAmountCorrectionsRequired; } /** * Method to check whether Invoice contains secondary tax amount or not. * * @param {@link InvoiceVO} value object contains invoice information. * * @return boolean value to indicate whether invoice contains secondary tax amount or not. */ private boolean doesInvoiceContainSecondaryTaxAmount(final InvoiceVO invoiceVO) { return invoiceVO != null && invoiceVO.getTaxAmount2() != null && invoiceVO.getTaxAmount2().compareTo(BD_ZERO) > 0; } /** * Method to check whether Delivery Charge value is entered or not. * * @return boolean value to indicate whether Delivery Charge value is entered or not. */ private boolean isDeliveryChargeApplicable() { final String methodSpec = "FinalizeInvoiceBaseController.isDeliveryChargeApplicable - "; logger.debug(methodSpec); boolean isDeliveryChargeEntered = false; final String deliveryChargeValue = finalizeBaseDialog.fldDeliveryCharge.getText(); try { if (deliveryChargeValue != null && deliveryChargeValue.trim().length() > 0 && Double.parseDouble(deliveryChargeValue) != 0) { isDeliveryChargeEntered = true; } } catch(Exception exception){ logger.warn(methodSpec + "Entered Delivery Charge Value is Invalid "); } return isDeliveryChargeEntered; } /** * Method to check whether Misc. Charge value is entered or not. * * @return boolean value to indicate whether Misc. Charge value is entered or not. */ private boolean isMiscChargeApplicable() { final String methodSpec = "FinalizeInvoiceBaseController.isMiscChargeApplicable - "; logger.debug(methodSpec); boolean isMiscChargeEntered = false; final String miscChargeValue = finalizeBaseDialog.fldMiscAdjustments.getText(); try { if (miscChargeValue != null && miscChargeValue.trim().length() > 0 && Double.parseDouble(miscChargeValue) != 0) { isMiscChargeEntered = true; } } catch(Exception exception){ logger.warn(methodSpec + "Entered Misc. Charge Value is Invalid "); } return isMiscChargeEntered; } protected void changeTypeIfBopisPaymentFailed() { if(salesOrderVO!= null) { try { clientApplicationContext.getOrderingDAO().updateRefOrderType(salesOrderVO.getId(), salesOrderVO.getLoc()); } catch (ApplicationException applicationException) { logger.error("Error occured while updating Order Type When Bopis Invoice Failed and treat as normal invoice " + applicationException); } } } private void delegateToAllowRetryAndLocalFunding(final PaymentEvent pe) { BOPISLogger.getInstance().setStoreProfile(invoiceVO.getLOC()).addBOPISLog(Constants.DEBUG, "delegateToAllowRetryAndLocalFunding starts"); new Thread() { public void run() { /* * This is an existing design used by TAMSII code to use join when showing dialog on * top of dialog. This will provide enough time for swing to redirect focus to top * window. */ try { join(120); } catch (InterruptedException ee) { logger.debug(ee.getMessage(), ee); } try { SwingUtilities.invokeAndWait(new Runnable() { public void run() { /* * Call is embedded into a Thread as this call will display dialog on * top of 'Checkout' screen. There is always a possibility of focus * problem when multiple screen overlap each other. Call inside thread * will almost kill that possibility. */ AllowRetryAndLocalFundingDialog allowRetryAndLocalFundingDialog = (AllowRetryAndLocalFundingDialog) allowRetryAndLocalFundingController .getView(); allowRetryAndLocalFundingController.disableEditing(true); String btnRetryName = allowRetryAndLocalFundingDialog.btnRetry .getText(); btnRetryName = btnRetryName.substring(0, btnRetryName.indexOf("(")); allowRetryAndLocalFundingDialog.btnRetry.setText(btnRetryName + "(" + retryCounter + ")"); if (retryCounter == 0) { allowRetryAndLocalFundingDialog.btnRetry.setEnabled(false); } int allowRetryAndLocalFundingDialogAction = allowRetryAndLocalFundingController .show(); logger.debug("action " + allowRetryAndLocalFundingDialogAction); BOPISLogger.getInstance().setStoreProfile(invoiceVO.getLOC()).addBOPISLog(Constants.INFO, "action " + allowRetryAndLocalFundingDialogAction); if (allowRetryAndLocalFundingDialogAction == AllowRetryAndLocalFundingController.RETRY) { retryCounter--; paymentController.setAllowBopisPaymentValidation(true); paymentController.getPnlPayment().btnSubmit.doClick(); } else if (allowRetryAndLocalFundingDialogAction == AllowRetryAndLocalFundingController.LOCAL_FUNDING) { allowRetryAndLocalFundingDialog.btnRetry.setEnabled(true); paymentController.displayPaymentPanel(DEFAULTPANEL); paymentController.setAllowBopisPaymentValidation(true); localFunding(pe); } } }); } catch (InterruptedException interruptedException) { logger.error(interruptedException.getMessage(), interruptedException); } catch (InvocationTargetException invocationTargetException) { logger.error(invocationTargetException.getMessage(), invocationTargetException); } } }.start(); BOPISLogger.getInstance().setStoreProfile(invoiceVO.getLOC()).addBOPISLog(Constants.DEBUG, "delegateToAllowRetryAndLocalFunding ends"); } private String getLocalizedText(final String labelName) { return clientApplicationContext.getResourceBundleReader().getLocalizedText( ResourceBundleReader.UI, labelName, clientApplicationContext.getCurrentLocale()); } private Vector getLoyaltyEligibleLineItems(final InvoiceVO invoiceVO) { Vector lineItems = null; try { lineItems = InvoiceBL.getLoyaltyEligibleLineItems(invoiceVO); } catch (ApplicationException applicationException) { logger.error(applicationException.getMessage(), applicationException); lineItems = null; } return lineItems; } private boolean sendNXPInterstoreUpdateSalesOrderRequest( InvoiceVO invoiceVO, boolean isCancelInvoice) { boolean orderNotificationStatusValue = false; try { OrderNotificationStatus orderNotificationStatus = clientApplicationContext .getInvoiceDAO().sendNXPInterstoreUpdateNotification( invoiceVO, isCancelInvoice); if (orderNotificationStatus != null) { orderNotificationStatusValue = orderNotificationStatus .isSuccess(); return orderNotificationStatusValue; } } catch (ApplicationException e) { logger.error(e.toString(), e); } return orderNotificationStatusValue; } private void reCalculateInvoiceTotal(final InvoiceVO invoiceVO) { final String methodSpec = "FinalizeInvoiceBaseController.reCalculateInvoiceTotal - "; logger.debug(methodSpec); final Vector invoiceLineItems = invoiceVO.getLineItems(); BigDecimal invoiceTotal = invoiceVO.getInvoiceTotal(); logger.debug(methodSpec + "mainInvoiceTotal = " + invoiceTotal); BOPISLogger.getInstance().setStoreProfile(invoiceVO.getLOC()).addBOPISLog(Constants.INFO, methodSpec + "mainInvoiceTotal = " + invoiceTotal); if (invoiceLineItems != null && invoiceLineItems.size() > 0) { // Re-Calculate Invoice Total BigDecimal newAlternateCoreSubTotal = BD_ZERO; BigDecimal newSubtotal = BD_ZERO; BigDecimal newInvoiceTotal = BD_ZERO; int invoiceLineItemsSize = invoiceLineItems.size(); logger.debug(methodSpec + "invoiceLineItemsSize = " + invoiceLineItemsSize); BOPISLogger.getInstance().setStoreProfile(invoiceVO.getLOC()).addBOPISLog(Constants.INFO, methodSpec + "invoiceLineItemsSize = " + invoiceLineItemsSize); for (int index = 0; index < invoiceLineItemsSize; index++) { InvoiceLineItemVO invoiceLineItem = (InvoiceLineItemVO) invoiceLineItems .elementAt(index); if (invoiceLineItem instanceof BaseLineItemVO) { BaseLineItemVO baseLineItem = (BaseLineItemVO) invoiceLineItem; if (baseLineItem.isCoreItem() || (baseLineItem.getCoreTransaction() != null && baseLineItem .getCoreTransaction().equals(Boolean.TRUE))) { newAlternateCoreSubTotal = newAlternateCoreSubTotal.add(baseLineItem .getExtendedPrice()); } else { newSubtotal = newSubtotal.add(baseLineItem.getExtendedPrice()); } } } newAlternateCoreSubTotal = newAlternateCoreSubTotal.setScale(2, BigDecimal.ROUND_HALF_UP); newSubtotal = newSubtotal.setScale(2, BigDecimal.ROUND_HALF_UP); logger.debug(methodSpec + "New Alternate CoreSubTotal = " + newAlternateCoreSubTotal); logger.debug(methodSpec + "New subtotal = " + newSubtotal); BOPISLogger.getInstance().setStoreProfile(invoiceVO.getLOC()).addBOPISLog(Constants.INFO, methodSpec + "New Alternate CoreSubTotal = " + newAlternateCoreSubTotal + "New subtotal = " + newSubtotal); newInvoiceTotal = newSubtotal; if (isDeliveryChecked()) { newInvoiceTotal = newInvoiceTotal.add(invoiceVO.getDeliveryCharge()); } newInvoiceTotal = newInvoiceTotal.add(invoiceVO.getMiscAdjustments()); newInvoiceTotal = newInvoiceTotal.add(invoiceVO.getTaxAmount1()); newInvoiceTotal = newInvoiceTotal.add(invoiceVO.getTaxAmount2()); if (isNapaRewardProgram || (isBopisInvoice)) { newInvoiceTotal = newInvoiceTotal.add(invoiceVO.getRewardAmount()); } newInvoiceTotal = newInvoiceTotal.setScale(2, BigDecimal.ROUND_HALF_UP); logger.debug(methodSpec + "Re Calculated Invoice Total = " + newInvoiceTotal); BOPISLogger.getInstance().setStoreProfile(invoiceVO.getLOC()).addBOPISLog(Constants.INFO, methodSpec + "Re Calculated Invoice Total = " + newInvoiceTotal); if (invoiceTotal.compareTo(newInvoiceTotal) > 0 && newAlternateCoreSubTotal != null && newAlternateCoreSubTotal.compareTo(BD_ZERO) != 0) { invoiceTotal = invoiceTotal.subtract(newAlternateCoreSubTotal); if (invoiceTotal.compareTo(newInvoiceTotal) == 0) { logger.debug(methodSpec + "Remove Core Amount = " + newAlternateCoreSubTotal + " from main invoice "); BOPISLogger.getInstance().setStoreProfile(invoiceVO.getLOC()).addBOPISLog(Constants.INFO, methodSpec + "Remove Core Amount = " + newAlternateCoreSubTotal + " from main invoice "); invoiceVO.setInvoiceTotal(invoiceTotal); } } } } private boolean isInValidCustomerName(CEPDIStatusVO cepdiStatusVO) { return cepdiStatusVO.getErrorCode().equalsIgnoreCase("40144") || cepdiStatusVO.getErrorCode().equalsIgnoreCase("40145") || cepdiStatusVO.getErrorCode().equalsIgnoreCase("40146") || cepdiStatusVO.getErrorMessage().contains("Nombre"); } private boolean isInValidCustomerPostalCode(CEPDIStatusVO cepdiStatusVO) { return cepdiStatusVO.getErrorCode().equalsIgnoreCase("40144") || cepdiStatusVO.getErrorCode().equalsIgnoreCase("40145") || cepdiStatusVO.getErrorCode().equalsIgnoreCase("40146") || cepdiStatusVO.getErrorMessage().contains("DomicilioFiscalReceptor"); } private boolean isInvalidCustomerRFC(CEPDIStatusVO cepdiStatusVO) { return cepdiStatusVO.getErrorCode().equalsIgnoreCase("40143") || cepdiStatusVO.getErrorMessage().contains("Rfc"); } /** * This method Add/Remove CDF line and adjust invoice totals accordingly. * * @param isdeliveryChecked - True/False */ protected void handleCDFLine(boolean isdeliveryChecked) { if (getStoreProfile() != null && customerVO != null && getStoreProfile().getRetailDeliveryFee().equalsIgnoreCase(customerVO.getState()) && invoiceVO != null && (invoiceVO.getTaxAmount1().compareTo(BigDecimal.ZERO) > 0 || invoiceVO.getTaxAmount2().compareTo(BigDecimal.ZERO) > 0)) { InvoicingProfileVO invoicingProfile = clientApplicationContext.getProfile(Profile.POINT_OF_SALE_CLIENT, clientApplicationContext.getLocation()).getInvoicingProfile(); if (!invoiceVO.isCoroladoFeeLineExists() && isdeliveryChecked) { // Add CDF Line final BaseLineItemVO bliVO = InvoiceLineBL.createCODeliveryFeeLineItem(invoiceVO, customerVO); removeRewardLineItemIfExists(); PointOfSaleEventDispatcher.getInstance().fireInvoiceLineItemAdded( new PointOfSaleListEvent(this, bliVO)); clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "10601"); bdInvoiceSubtotal = bdInvoiceSubtotal.add(invoicingProfile.getRetailDeliveryFeeAmount()); } else if (invoiceVO.isCoroladoFeeLineExists() && !isdeliveryChecked) { // Remove CDF Line InvoiceLineBL.removeCODeliveryLineItem(invoiceVO); removeRewardLineItemIfExists(); clientApplicationContext.getPointOfSaleEventDispatcher().fireInvoiceLineItemDeleted( new PointOfSaleListEvent(this, invoiceVO)); PointOfSaleEventDispatcher.getInstance().fireInvoiceTotalChanged(new InvoiceEvent(this, invoiceVO)); clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "10602"); bdInvoiceSubtotal = bdInvoiceSubtotal.subtract(invoicingProfile.getRetailDeliveryFeeAmount()); } bdInvoiceSubtotal = bdInvoiceSubtotal.setScale(2, BigDecimal.ROUND_HALF_UP); finalizeBaseDialog.dlblSubtotal.setText(bdInvoiceSubtotal.toString()); calculateInvoiceTotal(); //Setting correct Amount Applied to calculate remaining balance. if(isChargeInvoice() && !isdeliveryChecked && bdInvoiceTotal.doubleValue() > 0) { InvoicePaymentVO ipVO = (InvoicePaymentVO) invoiceListModel.get(0); ipVO.setAmountTendered(bdInvoiceTotal); ipVO.setAmountApplied(bdInvoiceTotal); invoiceListModel.set(0, ipVO); } } } /** * This method checks the barcode based gift cards exists or not. * * @param invoiceLineItems * @return true if barcode based NAPA gift cards exists else false */ private boolean doesBarcodeBasedNapaGiftCardLineItemExists(final Vector invoiceLineItems) { final String methodSpec = " FinalizeInvoiceBaseControlle.doesBarcodeBasedNapaGiftCardLineItemExists() - "; logger.debug(methodSpec); if (invoiceLineItems == null) { return false; } boolean giftCardExists = false; final int invoiceLineItemsSize = invoiceLineItems.size(); for (int i = 0; i < invoiceLineItemsSize; i++) { final InvoiceLineItemVO invoiceLineItem = (InvoiceLineItemVO) invoiceLineItems .elementAt(i); if (invoiceLineItem instanceof BaseLineItemVO) { if (((BaseLineItemVO) invoiceLineItem).getRefInvoiceLineItemTypeID() .intValue() == RefInvoiceLineItemType.NEW_NAPA_GIFT_CARD && ((BaseLineItemVO) invoiceLineItem).isNewGiftCard()) { giftCardExists = true; break; } } } logger.debug(methodSpec + " giftCardExists - " + giftCardExists); return giftCardExists; } /** * This method activates or reloads the Barcode based NAPA gift cards * * @param invoiceLineItems */ private boolean activateOrReloadBarcodeBasedNapaGiftCards(final Vector invoiceLineItems) { final String methodSpec = " FinalizeInvoiceBaseControlle.activateOrReloadBarcodeBasedNapaGiftCards() - "; logger.debug(methodSpec); boolean isCardActivated = true; HashMap failedLoadingMap = new HashMap(); BaseLineItemVO baseLineItemVO = null; boolean giftCardIsTheOnlyItemOnTheInvoiceLineItems = false; boolean isThereAnyOtherPartApartFromGft = false; for (int index = 0; index < invoiceLineItems.size(); index++) { final InvoiceLineItemVO invoiceLineItem = (InvoiceLineItemVO) invoiceLineItems .elementAt(index); if (invoiceLineItem instanceof BaseLineItemVO) { baseLineItemVO = (BaseLineItemVO) invoiceLineItem; if (baseLineItemVO.getRefInvoiceLineItemTypeID() .intValue() == RefInvoiceLineItemType.NEW_NAPA_GIFT_CARD) { giftCardIsTheOnlyItemOnTheInvoiceLineItems = true; } else { isThereAnyOtherPartApartFromGft = true; giftCardIsTheOnlyItemOnTheInvoiceLineItems = false; } if (baseLineItemVO.getRefInvoiceLineItemTypeID() .intValue() == RefInvoiceLineItemType.NEW_NAPA_GIFT_CARD && baseLineItemVO.isNewGiftCard() && !baseLineItemVO.isGiftCardActivateOrReload() && baseLineItemVO.getQuantityBilled().signum() > 0) { final String cardNumber = baseLineItemVO.getNewGiftCardNumber(); final BigDecimal loadAmount = baseLineItemVO.getUnitPrice(); // Activate gift card GiftCardResponse giftCardActivateResponse = GiftCardBL .activateAndAppyBalance(cardNumber, loadAmount, invoiceVO.getSourceOrderId()); if (giftCardActivateResponse != null && null != giftCardActivateResponse.getResponseDescription() && StringUtils.isNotEmpty(giftCardActivateResponse.getResponseDescription())) { final String responseDescription = giftCardActivateResponse .getResponseDescription(); if (responseDescription.equalsIgnoreCase(GiftCardConstants.ACTIVECARD)) { // Reload the gift card if it is already activated GiftCardResponse reloadGiftCardResponse = GiftCardBL .reloadGiftCardAmount(cardNumber, loadAmount, null, null, invoiceVO.getSourceOrderId()); if (reloadGiftCardResponse != null && null != reloadGiftCardResponse.getResponseDescription() && StringUtils.isNotEmpty( reloadGiftCardResponse.getResponseDescription()) && reloadGiftCardResponse.getResponseDescription() .equalsIgnoreCase(GiftCardConstants.APPROVED)) { baseLineItemVO.setGiftCardActivateOrReload(true); baseLineItemVO.setGiftCardAvailableBalance( reloadGiftCardResponse.getAvailableBalance()); logger.debug("Gift Card reload successful for card#:" + giftCardActivateResponse.getLastFour()); logger.debug("Gift Card Balance:" + giftCardActivateResponse.getAvailableBalance()); } else { failedLoadingMap.put( GiftCardConstants.MASKED_CARD_NUMBER .concat(cardNumber.substring(14)), new BigDecimal(loadAmount.toString())); removeGCFromInvoice(invoiceLineItems, cardNumber, loadAmount); index--; } } else if (responseDescription .equalsIgnoreCase(GiftCardConstants.ACTIVATED)) { baseLineItemVO.setGiftCardActivateOrReload(true); baseLineItemVO.setGiftCardActivated(true); baseLineItemVO.setGiftCardAvailableBalance(giftCardActivateResponse.getLoadedAmount()); logger.debug("Gift Card Activation successful for card#:" + giftCardActivateResponse.getLastFour()); logger.debug("LoadedAmount:" + giftCardActivateResponse.getLoadedAmount()); } else { failedLoadingMap.put( GiftCardConstants.MASKED_CARD_NUMBER .concat(cardNumber.substring(14)), new BigDecimal(loadAmount.toString())); removeGCFromInvoice(invoiceLineItems, cardNumber, loadAmount); index--; } } else { failedLoadingMap.put(GiftCardConstants.MASKED_CARD_NUMBER.concat(cardNumber.substring(14)), new BigDecimal(loadAmount.toString())); removeGCFromInvoice(invoiceLineItems, cardNumber, loadAmount); index--; } } } } if (failedLoadingMap != null && failedLoadingMap.size() > 0) { if(giftCardIsTheOnlyItemOnTheInvoiceLineItems && isThereAnyOtherPartApartFromGft == false) { giftCardErrorController.displayGiftCardErrorDialog( failedLoadingMap, GiftCardConstants.GIFT_CARD_ONLY_LOADING_ERROR); } else { giftCardErrorController.displayGiftCardErrorDialog( failedLoadingMap, GiftCardConstants.GIFT_CARD_LOADING_ERROR); } isCardActivated = false; // If there are no items in invoice, close checkout if (null != invoiceLineItems && invoiceLineItems.isEmpty()) { SwingUtilities.invokeLater(new Runnable() { public void run() { doCancel(); } }); } } return isCardActivated; } /** * This method releases hold amount to gift card. * * @param invoicePaymentVO contains invoice payment details. * @return true if gift card amount release otherwise false */ private boolean releaseGiftCardHoldAmount(final InvoicePaymentVO invoicePaymentVO) { final String methodSpec = " FinalizeInvoiceBaseController.releaseGiftCardHoldAmount() - "; logger.debug(methodSpec); boolean doesReleaseHoldAmount = true; HashMap failedReleaseMap = new HashMap(); String holdCashPayoutReferenceNumber = invoicePaymentVO.getGiftCardCashPayoutTransactionReferenceNum(); BigDecimal holdCashPayoutAmount = invoicePaymentVO.getGiftCardCashPayoutAmount(); GiftCardResponse releaseGiftCardAmountResponse = GiftCardBL.reverseGiftCardHoldAmount( invoicePaymentVO.getAmountTendered(), invoicePaymentVO.getGiftCardTransactionReferenceNum(),holdCashPayoutReferenceNumber,holdCashPayoutAmount); if (releaseGiftCardAmountResponse != null) { logger.debug(methodSpec + " reversalGiftCardAmountResponse= " + releaseGiftCardAmountResponse); final String responseDescription = releaseGiftCardAmountResponse .getResponseDescription(); if (StringUtils.isNotEmpty(responseDescription)) { if (GiftCardConstants.APPROVED.equalsIgnoreCase(responseDescription)) { logger.debug(methodSpec); } else if (GiftCardConstants.DECLINED.equalsIgnoreCase(responseDescription)) { logger.debug(methodSpec); clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "10721", new String[] { invoicePaymentVO.getAmountTendered().toString(), releaseGiftCardAmountResponse.toString() }); } } else if (releaseGiftCardAmountResponse.getErrors() != null && releaseGiftCardAmountResponse.getErrors().length > 0) { StringBuffer errorMessage = new StringBuffer(); Arrays.stream(releaseGiftCardAmountResponse.getErrors()) .forEach(error -> errorMessage.append(error.getErrorCode()).append(":") .append(error.getMessage()).append("\n")); clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "10722", new String[] { invoicePaymentVO.getAmountTendered().toString(), errorMessage.toString() }); } } else { logger.error(methodSpec); failedReleaseMap.put(getMaskedGiftCardNumber(invoicePaymentVO.getCreditCardOrCheckNum()), invoicePaymentVO.getAmountTendered()); giftCardPaymentErrorController.displayGiftCardErrorDialog( failedReleaseMap, GiftCardConstants.RELEASE_FAILED); } return doesReleaseHoldAmount; } /** * This method calls gift card v2 Payment Debit Service. * @return Boolean - True/False. */ private boolean processGiftCardDebitTransaction(Vector paymentsTendered, boolean isRetryAttempt) { final String methodSpec = " FinalizeInvoiceBaseController.processDebitTransaction() - "; logger.error(methodSpec); boolean isFundDebitedFromCard = true; HashMap declinedPaymentMap = new HashMap(); Vector failedPayments = new Vector(); if(paymentsTendered != null && paymentsTendered.size() > 0) { for (Object payments : paymentsTendered) { InvoicePaymentVO invoicePayment = (InvoicePaymentVO) payments; if (invoicePayment.getTenderTypeID().intValue() == RefTenderType.NEW_NAPA_GIFT_CARD && invoicePayment.isBarcodeBasedGiftCard() && invoicePayment.getAmountTendered().signum()>0) { GiftCardResponse giftCardDebitResponse = null; String holdTransactionReferenceNumber = invoicePayment.getGiftCardTransactionReferenceNum(); String holdCashPayoutReferenceNumber = invoicePayment.getGiftCardCashPayoutTransactionReferenceNum(); BigDecimal holdCashPayoutAmount = invoicePayment.getGiftCardCashPayoutAmount(); BigDecimal amountTendered = invoicePayment.getAmountTendered(); if (holdTransactionReferenceNumber == null) { clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "10712"); return false; } //Calling debit Service if (!invoicePayment.isGiftCardPaymentAlreadyApproved().booleanValue()) { giftCardDebitResponse = GiftCardBL.debitGiftCard(customerVO, amountTendered, holdTransactionReferenceNumber,holdCashPayoutReferenceNumber,holdCashPayoutAmount, GiftCardConstants.CAPTURE_COMPLETE_TRANSACTION); } else { //Go to next payment. continue; } /* Handle Response */ if (giftCardDebitResponse != null) { logger.debug(methodSpec + " giftCardDebitResponse = " + giftCardDebitResponse); if (StringUtils.isNotEmpty(giftCardDebitResponse.getResponseDescription())) { if (giftCardDebitResponse.getResponseDescription().equalsIgnoreCase( GiftCardConstants.APPROVED)) { invoicePayment.setGiftCardPaymentAlreadyApproved(Boolean.TRUE); invoicePayment.setGiftCardBalanceAmount(giftCardDebitResponse.getAvailableBalance()); if(holdCashPayoutReferenceNumber != null) { clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "10728"); bdBalanceDue = bdBalanceDue.add(holdCashPayoutAmount); finalizeBaseDialog.dlblChangeDue.setText( bdBalanceDue.toString() ); } } else if (giftCardDebitResponse.getResponseDescription().equalsIgnoreCase( GiftCardConstants.DECLINED)) { logger.error("isRetryAttempt" +isRetryAttempt); if (!isRetryAttempt) { declinedPaymentMap.put(getMaskedGiftCardNumber( invoicePayment.getCreditCardOrCheckNum()), amountTendered); } else { //Retry declines will be considered as failed payment. failedPayments.add(invoicePayment); } } } else if (giftCardDebitResponse.getErrors() != null && giftCardDebitResponse.getErrors().length > 0) { failedPayments.add(invoicePayment); } } else { failedPayments.add(invoicePayment); } } } } //Handle failure payments. if(((declinedPaymentMap != null && declinedPaymentMap.size() > 0) || (failedPayments != null && failedPayments.size() > 0)) && !isRetryAttempt) { isFundDebitedFromCard = handleFailedAndDeclinedPayments(declinedPaymentMap, failedPayments); } return isFundDebitedFromCard; } /** * This method handle gift card debit service failures. * @return Boolean - True/False. */ public boolean handleFailedAndDeclinedPayments(final HashMap declinedPaymentMap, final Vector failurePayments) { HashMap postRetriedFailuresMap = new HashMap(); if (declinedPaymentMap != null && declinedPaymentMap.size() > 0) { giftCardPaymentErrorController.displayGiftCardErrorDialog( declinedPaymentMap, GiftCardConstants.DECLINED); return false; } else if (failurePayments != null && failurePayments.size() > 0) { //Retry failure payments this.processGiftCardDebitTransaction(failurePayments, true); //check for unapproved payments Iterator payments = failurePayments.iterator(); while (payments.hasNext()) { InvoicePaymentVO payment = (InvoicePaymentVO) payments.next(); if (!payment.isGiftCardPaymentAlreadyApproved()) { postRetriedFailuresMap.put(getMaskedGiftCardNumber(payment.getCreditCardOrCheckNum()), payment.getAmountTendered()); } } //Display error message if still unapproved items exists. if(postRetriedFailuresMap.size() > 0) { giftCardPaymentErrorController.displayGiftCardErrorDialog( postRetriedFailuresMap, GiftCardConstants.FAILED); return false; } } return true; } /** * This method reload amount to gift card. * * @param giftCardNumber - Gift Card Number. * @param invoicePaymentVO contains invoice payment details. * @param reasonCode - the reasonCode for reload * @return true if gift card amount release otherwise false */ private boolean reloadGiftCardAmount(final InvoicePaymentVO invoicePaymentVO, final String reasonCode, final String giftCardNumber) { final String methodSpec = " FinalizeInvoiceBaseController.reloadGiftCardAmount() - "; logger.debug(methodSpec); boolean isReloadApproved = true; if(invoicePaymentVO.getGiftCardTransactionReferenceNum() != null) { GiftCardResponse reloadGiftCardAmountResponse = GiftCardBL.reloadGiftCardAmount( giftCardNumber, invoicePaymentVO.getAmountTendered(), invoicePaymentVO.getGiftCardTransactionReferenceNum(), reasonCode); if (reloadGiftCardAmountResponse != null) { logger.debug(methodSpec + " reloadGiftCardAmountResponse= " + reloadGiftCardAmountResponse); if (StringUtils.isNotEmpty(reloadGiftCardAmountResponse.getResponseDescription())) { if (reloadGiftCardAmountResponse.getResponseDescription().equalsIgnoreCase( GiftCardConstants.DECLINED)) { clientApplicationContext.getMessageMgr().showMessage( finalizeBaseDialog, "10713", new String[] { reloadGiftCardAmountResponse.getResponseDescription(), "$" + invoicePaymentVO.getAmountTendered() }); } } else if (reloadGiftCardAmountResponse.getErrors() != null && reloadGiftCardAmountResponse.getErrors().length > 0) { clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "10714", new String[] { invoicePaymentVO.getAmountTendered().toString()}); } } else { clientApplicationContext.getMessageMgr().showMessage(finalizeBaseDialog, "10714", new String[] { invoicePaymentVO.getAmountTendered().toString()}); } } return isReloadApproved; } /** * Update invoice note with last 4 digits of Gift Card number and append balance when activations/reloads are complete. * @param invoiceLineItems */ private void updateNoteWithCardNumAndBalance(Vector invoiceLineItems) { if (null != invoiceLineItems && !invoiceLineItems.isEmpty()) { final int invoiceLineItemsSize = invoiceLineItems.size(); for (int i = 0; i < invoiceLineItemsSize; i++) { final InvoiceLineItemVO invoiceLineItem = (InvoiceLineItemVO) invoiceLineItems.elementAt(i); if (invoiceLineItem instanceof InvoiceNoteVO) { InvoiceNoteVO nextNote = (InvoiceNoteVO) invoiceLineItem; if (nextNote.getRefInvoiceNoteTyepID().intValue() == RefInvoiceNoteType.NEW_NAPA_GIFT_CARD_MESSAGE ) { String noteText = nextNote.getText(); String partialCardNumNote = getNoteTextWithLastFourDigOfCardNum(noteText); if (nextNote.getGeneratedByLineItem() != null && nextNote.getGeneratedByLineItem().getGiftCardAvailableBalance() !=null) { nextNote.setText(getNoteTextWithBalance(partialCardNumNote, nextNote.getGeneratedByLineItem().getGiftCardAvailableBalance())); } else { nextNote.setText(partialCardNumNote); } } } } } } private String getNoteTextWithLastFourDigOfCardNum(String newGiftCardNote) { String noteText = newGiftCardNote; if (StringUtils.isNotEmpty(noteText)) { int index = newGiftCardNote.indexOf(":"); if (index != -1 && newGiftCardNote.length() > index + 18) { String lastFour = newGiftCardNote.substring(newGiftCardNote.length()-4); noteText = (newGiftCardNote.substring(0, index+1))+lastFour; } } return noteText; } private String getNoteTextWithBalance(String noteText, BigDecimal balance) { String balanceText = clientApplicationContext .getResourceBundleReader() .getLocalizedText(ResourceBundleReader.UI, "FinalizeInvoiceDialog.balance", clientApplicationContext.getCurrentLocale()); return (noteText + " "+balanceText+ balance); } private String getMaskedGiftCardNumber (String giftCardNumber) { String lastFourDigits = "Not Available"; if(giftCardNumber != null && StringUtils.isNotEmpty(giftCardNumber)) { lastFourDigits = giftCardNumber.length() == 4 ? giftCardNumber : giftCardNumber.substring(giftCardNumber.length() - 4); lastFourDigits = GiftCardConstants.MASKED_CARD_NUMBER.concat(lastFourDigits); } return lastFourDigits; } protected String getRemoteIPAddress(){ String remoteIPAddress = null; try { remoteIPAddress = PhoneRoomInvoiceBL.getRemoteIpAddress(invoiceVO.getRemoteStoreNumber()); } catch (ApplicationException e) { logger.error("Unable to fetch ip for remote store store"); } return remoteIPAddress; } protected InvoicingProfileVO getRemoteInvoicingProfileVO(){ InvoicingProfileVO invoicingProfileVO = null; invoicingProfileVO = taapRouter.getInvoicingProfile(getRemoteIPAddress()); return invoicingProfileVO; } protected boolean isBREInUse(){ return InvoiceBL.isBREInUse(); } protected boolean isValidateBREInvoice(){ return InvoiceBL.validateBusinessRulesforInvoice(invoiceVO,finalizeBaseDialog,BREAction.FINALIZE_INVOICE.toString()); } protected boolean useNapaGCV2(){ return InvoiceBL.useNapaGCv2(); } protected SalesOrderVO getSalesOrderVO(){ SalesOrderVO salesOrderVO = null; try { salesOrderVO = clientApplicationContext.getOrderingDAO() .getSalesOrderDetailsBySalesOrderId(invoiceVO.getSalesOrderVO().getId(), invoiceVO.getLOC().intValue()); } catch (ApplicationException e) { logger.error("Unable to fetch SalesOrderVO in FinalizeInvoiceBaseController"); } return salesOrderVO; } /** * This method add or remove the Colorado Delivery Fee line item. */ protected void addOrRemoveColoradoDeliveryFeeLineItem() { if (invoiceVO != null && InvoiceLineBL.isEligibleForColoradoDeliveryLaw(customerVO, getStoreProfile())) { Tax.recalculateTaxableSales(invoiceVO, false, (customerVO.getAlternateCoreCustomerID() == null), clientApplicationContext .getApplicationType() == ClientApplicationContext.TAMS_II, Profile.POINT_OF_SALE_CLIENT, customerVO); calculateInvoiceTotal(); // Add CDF line item if doesn't exist if (!invoiceVO.isCoroladoFeeLineExists() && ((invoiceVO.getSavedInvoiceIdForDeletion() != null && invoiceVO.getDeliveryFlag()) || invoiceVO.getSavedInvoiceIdForDeletion() == null) && (invoiceVO.getTaxAmount1().signum() > 0 || invoiceVO.getTaxAmount2().signum() > 0)) { final BaseLineItemVO coloradoRetailDeliveryLineItem = InvoiceLineBL .createCODeliveryFeeLineItem(invoiceVO, customerVO); PointOfSaleEventDispatcher.getInstance().fireInvoiceLineItemAdded( new PointOfSaleListEvent(this, coloradoRetailDeliveryLineItem)); PointOfSaleEventDispatcher.getInstance() .fireInvoiceTotalChanged(new InvoiceEvent(this, invoiceVO)); originalInvoiceVo = (InvoiceVO) invoiceVO.clone(); } // remove the CDF line item if Tax amount is less than or equal zero if (invoiceVO.isCoroladoFeeLineExists() && (((invoiceVO.getTaxAmount1() != null && invoiceVO.getTaxAmount1().compareTo(BigDecimal.ZERO) < 0) || (invoiceVO.getTaxAmount2() != null && invoiceVO.getTaxAmount2().compareTo(BigDecimal.ZERO) < 0)) || ((invoiceVO.getTaxAmount1() != null && invoiceVO.getTaxAmount1().compareTo(BigDecimal.ZERO) == 0) && (invoiceVO.getTaxAmount2() != null && invoiceVO.getTaxAmount2() .compareTo(BigDecimal.ZERO) == 0)))) { InvoiceLineBL.removeCODeliveryLineItem(invoiceVO); clientApplicationContext.getPointOfSaleEventDispatcher() .fireInvoiceLineItemDeleted(new PointOfSaleListEvent(this, invoiceVO)); PointOfSaleEventDispatcher.getInstance() .fireInvoiceTotalChanged(new InvoiceEvent(this, invoiceVO)); originalInvoiceVo = (InvoiceVO) invoiceVO.clone(); } } } /** * This method Removes the giftCard from Invoice and adjust invoice totals accordingly. * * @param isdeliveryChecked - True/False */ private void removeGCFromInvoice(Vector invoiceLineItems, String giftCardNumber, final BigDecimal amount) { final String methodSpec = "FinalizeInvoiceBaseController.removeGCfromInvoice - "; logger.debug(methodSpec); GiftCardBL.removeGCLineItem(invoiceLineItems, giftCardNumber); clientApplicationContext.getPointOfSaleEventDispatcher() .fireInvoiceLineItemDeleted(new PointOfSaleListEvent(this, invoiceVO)); PointOfSaleEventDispatcher.getInstance() .fireInvoiceTotalChanged(new InvoiceEvent(this, invoiceVO)); bdInvoiceSubtotal = bdInvoiceSubtotal.subtract(amount); bdInvoiceSubtotal = bdInvoiceSubtotal.setScale(2, BigDecimal.ROUND_HALF_UP); finalizeBaseDialog.dlblSubtotal.setText(bdInvoiceSubtotal.toString()); if ((customerVO != null) && (customerVO.getBillTypeCode() != null) && !(customerVO.getBillTypeCode().equalsIgnoreCase(RefBillingType.CHARGE_ONLY))) { removePaymentTendered(); } calculateInvoiceTotal(); // Setting correct Amount Applied to calculate remaining balance for charge invoice. if (isChargeInvoice() && bdInvoiceTotal.doubleValue() > 0) { InvoicePaymentVO ipVO = (InvoicePaymentVO) invoiceListModel.get(0); ipVO.setAmountTendered(bdInvoiceTotal); ipVO.setAmountApplied(bdInvoiceTotal); invoiceListModel.set(0, ipVO); computeAndDisplayBalanceDue(); } } public boolean processBarcodedNapaGiftCardCashPayoutTransaction(final Vector invoiceLineItems, Container container, CustomerVO customerVO) { final String methodSpec = "FinalizeInvoiceBaseController.processBarcodedNapaGiftCardCashPayoutTransaction - "; logger.debug(methodSpec); boolean giftCardCashPayoutTransactionSuccessful = true; HashMap failedRefundTransactionsMap = new HashMap(); if (invoiceLineItems != null) { BaseLineItemVO baseLineItemVO = null; InvoiceLineItemVO invoiceLineItem = null; for (int index = 0; index < invoiceLineItems.size(); index++) { invoiceLineItem = (InvoiceLineItemVO) invoiceLineItems.elementAt(index); if (invoiceLineItem instanceof BaseLineItemVO) { baseLineItemVO = (BaseLineItemVO) invoiceLineItem; final String cardNumber = baseLineItemVO.getNewGiftCardNumber(); BigDecimal cashPayoutAmount = baseLineItemVO.getUnitPrice(); cashPayoutAmount = cashPayoutAmount != null ? cashPayoutAmount.negate() : cashPayoutAmount; if (baseLineItemVO.getRefInvoiceLineItemTypeID() .intValue() == RefInvoiceLineItemType.NEW_NAPA_GIFT_CARD && baseLineItemVO.isNewGiftCard() && !baseLineItemVO.isGiftCardDebited() && baseLineItemVO.getQuantityBilled().signum() < 0) { if (baseLineItemVO.isCashPayoutEligible() && StringUtils .isNotEmpty(baseLineItemVO.getGiftCardTransactionReferenceId())) { final GiftCardResponse giftCardCashPayoutDebitServiceResponse = GiftCardBL .giftCardCashPayoutDebit(baseLineItemVO.getUnitPrice(), customerVO, baseLineItemVO.getGiftCardTransactionReferenceId(), GiftCardConstants.CAPTURE_COMPLETE_TRANSACTION); if (!processGiftCardCashPayoutDebitServiceResponse( giftCardCashPayoutDebitServiceResponse, baseLineItemVO)) { giftCardCashPayoutTransactionSuccessful = false; failedRefundTransactionsMap.put(GiftCardConstants.MASKED_CARD_NUMBER .concat(cardNumber.substring(14)), cashPayoutAmount); removeGCFromInvoice(invoiceLineItems, baseLineItemVO.getNewGiftCardNumber(), cashPayoutAmount); index--; } } else { failedRefundTransactionsMap.put(GiftCardConstants.MASKED_CARD_NUMBER .concat(cardNumber.substring(14)), cashPayoutAmount); removeGCFromInvoice(invoiceLineItems, baseLineItemVO.getNewGiftCardNumber(), cashPayoutAmount); giftCardCashPayoutTransactionSuccessful = false; index--; } } } } } if (failedRefundTransactionsMap != null && failedRefundTransactionsMap.size() > 0) { giftCardErrorController.displayGiftCardErrorDialog(failedRefundTransactionsMap, GiftCardConstants.GIFT_CARD_REFUND_ERROR); giftCardCashPayoutTransactionSuccessful = false; GiftCardBL.removeRewardLineItemIfExists(invoiceLineItems); // If there are no items in invoice, close checkout if (invoiceLineItems != null && invoiceLineItems.isEmpty()) { doCancel(); } } return giftCardCashPayoutTransactionSuccessful; } private boolean processGiftCardCashPayoutDebitServiceResponse( final GiftCardResponse giftCardCashPayoutDebitServiceResponse, final BaseLineItemVO baseLineItemVO) { final String methodSpec = "FinalizeInvoiceBaseController.processGiftCardDebitServiceResponse - "; logger.debug(methodSpec); if (giftCardCashPayoutDebitServiceResponse != null) { final String giftCardCashPayoutDebitServiceResponseDescription = giftCardCashPayoutDebitServiceResponse .getResponseDescription(); if (StringUtils.isNotEmpty(giftCardCashPayoutDebitServiceResponseDescription) && giftCardCashPayoutDebitServiceResponseDescription .equalsIgnoreCase(GiftCardConstants.APPROVED)) { baseLineItemVO.setGiftCardDebited(true); return true; } } return false; } }