blob: ced15769eea9e8ce96baed4496f77545f270067e [file] [log] [blame]
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*******************************************************************************/
package org.ofbiz.pos;
import java.io.PrintWriter;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;
import javolution.util.FastList;
import javolution.util.FastMap;
import net.xoetrope.xui.data.XModel;
import net.xoetrope.xui.helper.SwingWorker;
import org.ofbiz.accounting.payment.PaymentGatewayServices;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.GeneralException;
import org.ofbiz.base.util.Log4jLoggerWriter;
import org.ofbiz.base.util.UtilDateTime;
import org.ofbiz.base.util.UtilFormatOut;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.UtilNumber;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.base.util.collections.LifoSet;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.entity.condition.EntityCondition;
import org.ofbiz.entity.condition.EntityFunction;
import org.ofbiz.entity.condition.EntityOperator;
import org.ofbiz.entity.model.DynamicViewEntity;
import org.ofbiz.entity.model.ModelKeyMap;
import org.ofbiz.entity.transaction.GenericTransactionException;
import org.ofbiz.entity.transaction.TransactionUtil;
import org.ofbiz.entity.util.EntityFindOptions;
import org.ofbiz.entity.util.EntityListIterator;
import org.ofbiz.entity.util.EntityUtil;
import org.ofbiz.guiapp.xui.XuiSession;
import org.ofbiz.order.shoppingcart.CartItemModifyException;
import org.ofbiz.order.shoppingcart.CheckOutHelper;
import org.ofbiz.order.shoppingcart.ItemNotFoundException;
import org.ofbiz.order.shoppingcart.ShoppingCart;
import org.ofbiz.order.shoppingcart.ShoppingCartItem;
import org.ofbiz.order.shoppinglist.ShoppingListEvents;
import org.ofbiz.party.contact.ContactMechWorker;
import org.ofbiz.pos.component.Journal;
import org.ofbiz.pos.component.Output;
import org.ofbiz.pos.device.DeviceLoader;
import org.ofbiz.pos.device.impl.Receipt;
import org.ofbiz.pos.screen.ClientProfile;
import org.ofbiz.pos.screen.LoadSale;
import org.ofbiz.pos.screen.PosScreen;
import org.ofbiz.pos.screen.SaveSale;
import org.ofbiz.product.config.ProductConfigWrapper;
import org.ofbiz.product.config.ProductConfigWrapper.ConfigOption;
import org.ofbiz.product.product.ProductWorker;
import org.ofbiz.product.store.ProductStoreWorker;
import org.ofbiz.service.GenericServiceException;
import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.service.ServiceUtil;
@SuppressWarnings("serial")
public class PosTransaction implements Serializable {
public static final int scale = UtilNumber.getBigDecimalScale("order.decimals");
public static final int rounding = UtilNumber.getBigDecimalRoundingMode("order.rounding");
public static final BigDecimal ZERO = (BigDecimal.ZERO).setScale(scale, rounding);
public static final String resource = "PosUiLabels";
public static final String module = PosTransaction.class.getName();
public static final int NO_PAYMENT = 0;
public static final int INTERNAL_PAYMENT = 1;
public static final int EXTERNAL_PAYMENT = 2;
private static PrintWriter defaultPrintWriter = new Log4jLoggerWriter(Debug.getLogger(module));
private static PosTransaction currentTx = null;
private static LifoSet<PosTransaction> savedTx = new LifoSet<PosTransaction>();
protected XuiSession session = null;
protected ShoppingCart cart = null;
protected CheckOutHelper ch = null;
protected PrintWriter trace = null;
protected GenericValue txLog = null;
protected String productStoreId = null;
protected String transactionId = null;
protected String facilityId = null;
protected String terminalId = null;
protected String currency = null;
protected String orderId = null;
protected String partyId = null;
protected Locale locale = null;
protected boolean isOpen = false;
protected int drawerIdx = 0;
private GenericValue shipAddress = null;
private Map<String, Integer> skuDiscounts = FastMap.newInstance();
private int cartDiscount = -1;
public PosTransaction(XuiSession session) {
this.session = session;
this.terminalId = session.getId();
this.partyId = "_NA_";
this.trace = defaultPrintWriter;
this.productStoreId = (String) session.getAttribute("productStoreId");
this.facilityId = (String) session.getAttribute("facilityId");
this.currency = (String) session.getAttribute("currency");
// this.locale = (Locale) session.getAttribute("locale"); This is legacy code and may come (demo) from ProductStore.defaultLocaleString defined in demoRetail and is incompatible with how localisation is handled in the POS
this.locale = Locale.getDefault();
this.cart = new ShoppingCart(session.getDelegator(), productStoreId, locale, currency);
this.ch = new CheckOutHelper(session.getDispatcher(), session.getDelegator(), cart);
cart.setChannelType("POS_SALES_CHANNEL");
cart.setTransactionId(transactionId);
cart.setFacilityId(facilityId);
cart.setTerminalId(terminalId);
if (session.getUserLogin() != null) {
cart.addAdditionalPartyRole(session.getUserLogin().getString("partyId"), "SALES_REP");
}
// setup the TX log
this.transactionId = session.getDelegator().getNextSeqId("PosTerminalLog");
txLog = session.getDelegator().makeValue("PosTerminalLog");
txLog.set("posTerminalLogId", this.transactionId);
txLog.set("posTerminalId", terminalId);
txLog.set("transactionId", transactionId);
txLog.set("userLoginId", session.getUserId());
txLog.set("statusId", "POSTX_ACTIVE");
txLog.set("logStartDateTime", UtilDateTime.nowTimestamp());
try {
txLog.create();
} catch (GenericEntityException e) {
Debug.logError(e, "Unable to create TX log - not fatal", module);
}
currentTx = this;
trace("transaction created");
}
public XuiSession getSession() {
return session;
}
public String getUserId() {
return session.getUserId();
}
public String getPartyId() {
return partyId;
}
public void setPartyId(String partyId) {
this.partyId = partyId;
this.cart.setPlacingCustomerPartyId(partyId);
try {
this.cart.setUserLogin(session.getUserLogin(), session.getDispatcher());
} catch (CartItemModifyException e) {
Debug.logError(e, module);
}
}
public int getDrawerNumber() {
return drawerIdx + 1;
}
public void popDrawer() {
DeviceLoader.drawer[drawerIdx].openDrawer();
}
public String getTransactionId() {
return this.transactionId;
}
public String getTerminalId() {
return this.terminalId;
}
public String getFacilityId() {
return this.facilityId;
}
public String getTerminalLogId() {
return txLog.getString("posTerminalLogId");
}
public boolean isOpen() {
if (!this.isOpen) {
GenericValue terminalState = this.getTerminalState();
if (terminalState != null) {
this.isOpen = true;
} else {
this.isOpen = false;
}
}
return this.isOpen;
}
public boolean isEmpty() {
return (UtilValidate.isEmpty(cart));
}
public List<GenericValue> lookupItem(String sku) throws GeneralException {
return ProductWorker.findProductsById(session.getDelegator(), sku, null);
}
public String getOrderId() {
return this.orderId;
}
public BigDecimal getTaxTotal() {
return cart.getTotalSalesTax();
}
public BigDecimal getGrandTotal() {
return cart.getGrandTotal();
}
public int getNumberOfPayments() {
return cart.selectedPayments();
}
public BigDecimal getPaymentTotal() {
return cart.getPaymentTotal();
}
public BigDecimal getTotalDue() {
BigDecimal grandTotal = this.getGrandTotal();
BigDecimal paymentAmt = this.getPaymentTotal();
return grandTotal.subtract(paymentAmt);
}
public int size() {
return cart.size();
}
public Map<String, Object> getItemInfo(int index) {
ShoppingCartItem item = cart.findCartItem(index);
Map<String, Object> itemInfo = FastMap.newInstance();
itemInfo.put("productId", item.getProductId());
String description = item.getDescription();
if (UtilValidate.isEmpty(description)) {
itemInfo.put("description", item.getName());
} else {
itemInfo.put("description", description);
}
itemInfo.put("quantity", UtilFormatOut.formatQuantity(item.getQuantity()));
itemInfo.put("subtotal", UtilFormatOut.formatPrice(item.getItemSubTotal()));
itemInfo.put("isTaxable", item.taxApplies() ? "T" : " ");
itemInfo.put("discount", "");
itemInfo.put("adjustments", "");
if (item.getOtherAdjustments().compareTo(BigDecimal.ZERO) != 0) {
itemInfo.put("itemDiscount", UtilFormatOut.padString(
UtilProperties.getMessage(resource, "PosItemDiscount", locale), Receipt.pridLength[0] + 1, true, ' '));
itemInfo.put("adjustments", UtilFormatOut.formatPrice(item.getOtherAdjustments()));
}
if (isAggregatedItem(item.getProductId())) {
ProductConfigWrapper pcw = null;
pcw = item.getConfigWrapper();
itemInfo.put("basePrice", UtilFormatOut.formatPrice(pcw.getDefaultPrice()));
} else {
itemInfo.put("basePrice", UtilFormatOut.formatPrice(item.getBasePrice()));
}
return itemInfo;
}
public List<Map<String, Object>> getItemConfigInfo(int index) {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
// I think I need to initialize the list in a special way
// to use foreach in receipt.java
ShoppingCartItem item = cart.findCartItem(index);
if (this.isAggregatedItem(item.getProductId())) {
ProductConfigWrapper pcw = null;
pcw = item.getConfigWrapper();
List<ConfigOption> selected = pcw.getSelectedOptions();
for(ConfigOption configoption : selected) {
Map<String, Object> itemInfo = FastMap.newInstance();
if (configoption.isSelected() && !configoption.isDefault()) {
itemInfo.put("productId", "");
itemInfo.put("sku", "");
itemInfo.put("configDescription", configoption.getDescription(locale));
itemInfo.put("configQuantity", UtilFormatOut.formatQuantity(item.getQuantity()));
itemInfo.put("configBasePrice", UtilFormatOut.formatPrice(configoption.getOffsetPrice()));
//itemInfo.put("isTaxable", item.taxApplies() ? "T" : " ");
list.add(itemInfo);
}
}
}
return list;
}
public Map<String, Object> getPaymentInfo(int index) {
ShoppingCart.CartPaymentInfo inf = cart.getPaymentInfo(index);
GenericValue infValue = inf.getValueObject(session.getDelegator());
GenericValue paymentPref = null;
try {
Map<String, Object> fields = FastMap.newInstance();
fields.put("paymentMethodTypeId", inf.paymentMethodTypeId);
if (inf.paymentMethodId != null) {
fields.put("paymentMethodId", inf.paymentMethodId);
}
fields.put("maxAmount", inf.amount);
fields.put("orderId", this.getOrderId());
List<GenericValue> paymentPrefs = session.getDelegator().findByAnd("OrderPaymentPreference", fields);
if (UtilValidate.isNotEmpty(paymentPrefs)) {
//Debug.log("Found some prefs - " + paymentPrefs.size(), module);
if (paymentPrefs.size() > 1) {
Debug.logError("Multiple OrderPaymentPreferences found for the same payment method!", module);
} else {
paymentPref = EntityUtil.getFirst(paymentPrefs);
//Debug.log("Got the first pref - " + paymentPref, module);
}
} else {
Debug.logError("No OrderPaymentPreference found - " + fields, module);
}
} catch (GenericEntityException e) {
Debug.logError(e, module);
}
//Debug.log("PaymentPref - " + paymentPref, module);
Map<String, Object> payInfo = FastMap.newInstance();
// locate the auth info
GenericValue authTrans = null;
if (paymentPref != null) {
authTrans = PaymentGatewayServices.getAuthTransaction(paymentPref);
if (authTrans != null) {
payInfo.putAll(authTrans);
String authInfoString = "Ref: " + authTrans.getString("referenceNum") + " Auth: " + authTrans.getString("gatewayCode");
payInfo.put("authInfoString", authInfoString);
} else {
Debug.logError("No Authorization transaction found for payment preference - " + paymentPref, module);
}
} else {
Debug.logError("Payment preference is empty!", module);
return payInfo;
}
//Debug.log("AuthTrans - " + authTrans, module);
if ("PaymentMethodType".equals(infValue.getEntityName())) {
payInfo.put("description", (String) infValue.get("description", locale));
payInfo.put("payInfo", (String) infValue.get("description", locale));
payInfo.put("amount", UtilFormatOut.formatPrice(inf.amount));
} else {
String paymentMethodTypeId = infValue.getString("paymentMethodTypeId");
GenericValue pmt = null;
try {
pmt = infValue.getRelatedOne("PaymentMethodType");
} catch (GenericEntityException e) {
Debug.logError(e, module);
}
if (pmt != null) {
payInfo.put("description", (String) pmt.get("description", locale));
payInfo.put("amount", UtilFormatOut.formatPrice(inf.amount));
}
if ("CREDIT_CARD".equals(paymentMethodTypeId)) {
GenericValue cc = null;
try {
cc = infValue.getRelatedOne("CreditCard");
} catch (GenericEntityException e) {
Debug.logError(e, module);
}
String nameOnCard = cc.getString("firstNameOnCard") + " " + cc.getString("lastNameOnCard");
nameOnCard = nameOnCard.trim();
payInfo.put("nameOnCard", nameOnCard);
String cardNum = cc.getString("cardNumber");
String cardStr = UtilFormatOut.formatPrintableCreditCard(cardNum);
String expDate = cc.getString("expireDate");
String infoString = cardStr + " " + expDate;
payInfo.put("payInfo", infoString);
payInfo.putAll(cc);
payInfo.put("cardNumber", cardStr); // masked cardNumber
} else if ("GIFT_CARD".equals(paymentMethodTypeId)) {
@SuppressWarnings("unused")
GenericValue gc = null;
try {
gc = infValue.getRelatedOne("GiftCard"); //FIXME is this really useful ? (Maybe later...)
} catch (GenericEntityException e) {
Debug.logError(e, module);
}
}
}
return payInfo;
}
public BigDecimal getItemQuantity(String productId) {
trace("request item quantity", productId);
ShoppingCartItem item = cart.findCartItem(productId, null, null, null, BigDecimal.ZERO);
if (item != null) {
return item.getQuantity();
} else {
trace("item not found", productId);
return BigDecimal.ZERO;
}
}
public boolean isAggregatedItem(String productId) {
trace("is Aggregated Item", productId);
try {
Delegator delegator = cart.getDelegator();
GenericValue product = null;
product = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", productId));
if (UtilValidate.isNotEmpty(product) && "AGGREGATED".equals(product.getString("productTypeId"))) {
return true;
}
} catch (GenericEntityException e) {
trace("item lookup error", e);
Debug.logError(e, module);
} catch (Exception e) {
trace("general exception", e);
Debug.logError(e, module);
}
return false;
}
public ProductConfigWrapper getProductConfigWrapper(String productId) {
//Get a PCW for a new product
trace("get Product Config Wrapper", productId);
ProductConfigWrapper pcw = null;
try {
Delegator delegator = cart.getDelegator();
pcw = new ProductConfigWrapper(delegator, session.getDispatcher(),
productId, null, null, null, null, null, null);
} catch (ItemNotFoundException e) {
trace("item not found", e);
//throw e;
} catch (CartItemModifyException e) {
trace("add item error", e);
//throw e;
} catch (GenericEntityException e) {
trace("item lookup error", e);
Debug.logError(e, module);
} catch (Exception e) {
trace("general exception", e);
Debug.logError(e, module);
}
return pcw;
}
public ProductConfigWrapper getProductConfigWrapper(String productId, String cartIndex) {
// Get a PCW for a pre-configured product
trace("get Product Config Wrapper", productId + "/" + cartIndex);
ProductConfigWrapper pcw = null;
try {
int index = Integer.parseInt(cartIndex);
ShoppingCartItem product = cart.findCartItem(index);
pcw = product.getConfigWrapper();
} catch (Exception e) {
trace("general exception", e);
Debug.logError(e, module);
}
return pcw;
}
public void addItem(String productId, BigDecimal quantity) throws CartItemModifyException, ItemNotFoundException {
trace("add item", productId + "/" + quantity);
try {
Delegator delegator = cart.getDelegator();
GenericValue product = null;
ProductConfigWrapper pcw = null;
product = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", productId));
if (UtilValidate.isNotEmpty(product) && "AGGREGATED".equals(product.getString("productTypeId"))) {
// if it's an aggregated item, load the configwrapper and set to defaults
pcw = new ProductConfigWrapper(delegator, session.getDispatcher(), productId, null, null, null, null, null, null);
pcw.setDefaultConfig();
}
//cart.addOrIncreaseItem(productId, null, quantity, null, null, null, null, null, null, null, null, null, null, null, null, session.getDispatcher());
cart.addOrIncreaseItem(productId, null, quantity, null, null, null, null, null, null, null, null, pcw, null, null, null, session.getDispatcher());
} catch (ItemNotFoundException e) {
trace("item not found", e);
throw e;
} catch (CartItemModifyException e) {
trace("add item error", e);
throw e;
} catch (GenericEntityException e) {
trace("item lookup error", e);
Debug.logError(e, module);
} catch (Exception e) {
trace("general exception", e);
Debug.logError(e, module);
}
}
public void addItem(String productId, ProductConfigWrapper pcw)
throws ItemNotFoundException, CartItemModifyException {
trace("add item with ProductConfigWrapper", productId);
try {
cart.addOrIncreaseItem(productId, null, BigDecimal.ONE, null, null, null, null, null, null, null, null, pcw, null, null, null, session.getDispatcher());
} catch (ItemNotFoundException e) {
trace("item not found", e);
throw e;
} catch (CartItemModifyException e) {
trace("add item error", e);
throw e;
} catch (Exception e) {
trace("general exception", e);
Debug.logError(e, module);
}
}
public void modifyConfig(String productId, ProductConfigWrapper pcw, String cartIndex)
throws CartItemModifyException, ItemNotFoundException {
trace("modify item config", cartIndex);
try {
int cartIndexInt = Integer.parseInt(cartIndex);
ShoppingCartItem cartItem = cart.findCartItem(cartIndexInt);
BigDecimal quantity = cartItem.getQuantity();
cart.removeCartItem(cartIndexInt, session.getDispatcher());
cart.addOrIncreaseItem(productId, null, quantity, null, null, null, null, null, null, null, null, pcw, null, null, null, session.getDispatcher());
} catch (CartItemModifyException e) {
Debug.logError(e, module);
trace("void or add item error", productId, e);
throw e;
} catch (ItemNotFoundException e) {
trace("item not found", e);
throw e;
} catch (Exception e) {
trace("general exception", e);
Debug.logError(e, module);
}
return;
}
public void modifyQty(String productId, BigDecimal quantity) throws CartItemModifyException {
trace("modify item quantity", productId + "/" + quantity);
ShoppingCartItem item = cart.findCartItem(productId, null, null, null, BigDecimal.ZERO);
if (item != null) {
try {
item.setQuantity(quantity, session.getDispatcher(), cart, true);
} catch (CartItemModifyException e) {
Debug.logError(e, module);
trace("modify item error", e);
throw e;
}
} else {
trace("item not found", productId);
}
}
public void modifyPrice(String productId, BigDecimal price) {
trace("modify item price", productId + "/" + price);
ShoppingCartItem item = cart.findCartItem(productId, null, null, null, BigDecimal.ZERO);
if (item != null) {
item.setBasePrice(price);
} else {
trace("item not found", productId);
}
}
public void addDiscount(String productId, BigDecimal discount, boolean percent) {
GenericValue adjustment = session.getDelegator().makeValue("OrderAdjustment");
adjustment.set("orderAdjustmentTypeId", "DISCOUNT_ADJUSTMENT");
if (percent) {
adjustment.set("sourcePercentage", discount.movePointRight(2));
} else {
adjustment.set("amount", discount);
}
if (productId != null) {
trace("add item adjustment");
ShoppingCartItem item = cart.findCartItem(productId, null, null, null, BigDecimal.ZERO);
Integer itemAdj = skuDiscounts.get(productId);
if (itemAdj != null) {
item.removeAdjustment(itemAdj.intValue());
}
int idx = item.addAdjustment(adjustment);
skuDiscounts.put(productId, new Integer(idx));
} else {
trace("add sale adjustment");
if (cartDiscount > -1) {
cart.removeAdjustment(cartDiscount);
}
cartDiscount = cart.addAdjustment(adjustment);
}
}
public void clearDiscounts() {
if (cartDiscount > -1) {
cart.removeAdjustment(cartDiscount);
cartDiscount = -1;
}
for(String productId : skuDiscounts.keySet()) {
ShoppingCartItem item = cart.findCartItem(productId, null, null, null, BigDecimal.ZERO);
Integer itemAdj = skuDiscounts.remove(productId);
if (itemAdj != null) {
item.removeAdjustment(itemAdj.intValue());
}
}
}
public BigDecimal GetTotalDiscount() {
return cart.getOrderOtherAdjustmentTotal();
}
public void voidItem(String productId) throws CartItemModifyException {
trace("void item", productId);
ShoppingCartItem item = cart.findCartItem(productId, null, null, null, BigDecimal.ZERO);
if (item != null) {
try {
int itemIdx = cart.getItemIndex(item);
cart.removeCartItem(itemIdx, session.getDispatcher());
} catch (CartItemModifyException e) {
Debug.logError(e, module);
trace("void item error", productId, e);
throw e;
}
} else {
trace("item not found", productId);
}
}
public void voidSale(PosScreen pos) {
trace("void sale");
txLog.set("statusId", "POSTX_VOIDED");
txLog.set("itemCount", new Long(cart.size()));
txLog.set("logEndDateTime", UtilDateTime.nowTimestamp());
try {
txLog.store();
} catch (GenericEntityException e) {
Debug.logError(e, "Unable to store TX log - not fatal", module);
}
cart.clear();
pos.getPromoStatusBar().clear();
currentTx = null;
}
public void closeTx() {
trace("transaction closed");
txLog.set("statusId", "POSTX_CLOSED");
txLog.set("itemCount", new Long(cart.size()));
txLog.set("logEndDateTime", UtilDateTime.nowTimestamp());
try {
txLog.store();
} catch (GenericEntityException e) {
Debug.logError(e, "Unable to store TX log - not fatal", module);
}
cart.clear();
currentTx = null;
}
public void paidInOut(String type) {
trace("paid " + type);
txLog.set("statusId", "POSTX_PAID_" + type);
txLog.set("logEndDateTime", UtilDateTime.nowTimestamp());
try {
txLog.store();
} catch (GenericEntityException e) {
Debug.logError(e, "Unable to store TX log - not fatal", module);
}
currentTx = null;
}
public void calcTax() {
try {
ch.calcAndAddTax(this.getStoreOrgAddress());
} catch (GeneralException e) {
Debug.logError(e, module);
}
}
public void clearTax() {
cart.removeAdjustmentByType("SALES_TAX");
}
public int checkPaymentMethodType(String paymentMethodTypeId) {
Map<String, String> fields = UtilMisc.toMap("paymentMethodTypeId", paymentMethodTypeId, "productStoreId", productStoreId);
List<GenericValue> values = null;
try {
values = session.getDelegator().findByAndCache("ProductStorePaymentSetting", fields);
} catch (GenericEntityException e) {
Debug.logError(e, module);
}
final String externalCode = "PRDS_PAY_EXTERNAL";
if (UtilValidate.isEmpty(values)) {
return NO_PAYMENT;
} else {
boolean isExternal = true;
Iterator<GenericValue> i = values.iterator();
while (i.hasNext() && isExternal) {
GenericValue v = i.next();
//Debug.log("Testing [" + paymentMethodTypeId + "] - " + v, module);
if (!externalCode.equals(v.getString("paymentServiceTypeEnumId"))) {
isExternal = false;
}
}
if (isExternal) {
return EXTERNAL_PAYMENT;
} else {
return INTERNAL_PAYMENT;
}
}
}
public BigDecimal addPayment(String id, BigDecimal amount) {
return this.addPayment(id, amount, null, null);
}
public BigDecimal addPayment(String id, BigDecimal amount, String refNum, String authCode) {
trace("added payment", id + "/" + amount);
if ("CASH".equals(id)) {
// clear cash payments first; so there is only one
cart.clearPayment(id);
}
cart.addPaymentAmount(id, amount, refNum, authCode, true, true, false);
return this.getTotalDue();
}
public void setPaymentRefNum(int paymentIndex, String refNum, String authCode) {
trace("setting payment index reference number", paymentIndex + " / " + refNum + " / " + authCode);
ShoppingCart.CartPaymentInfo inf = cart.getPaymentInfo(paymentIndex);
inf.refNum[0] = refNum;
inf.refNum[1] = authCode;
}
/* CVV2 code should be entered when a card can't be swiped */
public void setPaymentSecurityCode(String paymentId, String refNum, String securityCode) {
trace("setting payment security code", paymentId);
int paymentIndex = cart.getPaymentInfoIndex(paymentId, refNum);
ShoppingCart.CartPaymentInfo inf = cart.getPaymentInfo(paymentIndex);
inf.securityCode = securityCode;
inf.isSwiped = false;
}
/* Track2 data should be sent to processor when a card is swiped. */
public void setPaymentTrack2(String paymentId, String refNum, String securityCode) {
trace("setting payment security code", paymentId);
int paymentIndex = cart.getPaymentInfoIndex(paymentId, refNum);
ShoppingCart.CartPaymentInfo inf = cart.getPaymentInfo(paymentIndex);
inf.securityCode = securityCode;
inf.isSwiped = true;
}
/* Postal code should be entered when a card can't be swiped */
public void setPaymentPostalCode(String paymentId, String refNum, String postalCode) {
trace("setting payment security code", paymentId);
int paymentIndex = cart.getPaymentInfoIndex(paymentId, refNum);
ShoppingCart.CartPaymentInfo inf = cart.getPaymentInfo(paymentIndex);
inf.postalCode = postalCode;
}
public void clearPayments() {
trace("all payments cleared from sale");
cart.clearPayments();
}
public void clearPayment(int index) {
trace("removing payment", "" + index);
cart.clearPayment(index);
}
public void clearPayment(String id) {
trace("removing payment", id);
cart.clearPayment(id);
}
public int selectedPayments() {
return cart.selectedPayments();
}
public void setTxAsReturn(String returnId) {
trace("returned sale");
txLog.set("statusId", "POSTX_RETURNED");
txLog.set("returnId", returnId);
txLog.set("logEndDateTime", UtilDateTime.nowTimestamp());
try {
txLog.store();
} catch (GenericEntityException e) {
Debug.logError(e, "Unable to store TX log - not fatal", module);
}
cart.clear();
currentTx = null;
}
public BigDecimal processSale(Output output) throws GeneralException {
trace("process sale");
BigDecimal grandTotal = this.getGrandTotal();
BigDecimal paymentAmt = this.getPaymentTotal();
if (grandTotal.compareTo(paymentAmt) > 0) {
throw new IllegalStateException();
}
// attach the party ID to the cart
cart.setOrderPartyId(partyId);
// Set the shipping type
cart.setShipmentMethodTypeId("NO_SHIPPING");
// cart.setCarrierPartyId();
// validate payment methods
output.print(UtilProperties.getMessage(resource, "PosValidating", locale));
Map<String, Object> valRes = ch.validatePaymentMethods();
if (valRes != null && ServiceUtil.isError(valRes)) {
throw new GeneralException(ServiceUtil.getErrorMessage(valRes));
}
// store the "order"
if (UtilValidate.isEmpty(this.orderId)) { // if order does not exist
output.print(UtilProperties.getMessage(resource, "PosSaving", locale));
Map<String, Object> orderRes = ch.createOrder(session.getUserLogin());
//Debug.log("Create Order Resp : " + orderRes, module);
if (orderRes != null && ServiceUtil.isError(orderRes)) {
throw new GeneralException(ServiceUtil.getErrorMessage(orderRes));
} else if (orderRes != null) {
this.orderId = (String) orderRes.get("orderId");
}
} else { // if the order has already been created
Map<?, ?> changeMap = UtilMisc.toMap("itemReasonMap",
UtilMisc.toMap("reasonEnumId", "EnumIdHere"), // TODO: where does this come from?
"itemCommentMap", UtilMisc.toMap("changeComments", "change Comments here")); //TODO
Map<String, Object> svcCtx = FastMap.newInstance();
svcCtx.put("userLogin", session.getUserLogin());
svcCtx.put("orderId", orderId);
svcCtx.put("shoppingCart", cart);
svcCtx.put("locale", locale);
svcCtx.put("changeMap", changeMap);
Map<String, Object> svcRes = null;
try {
LocalDispatcher dispatcher = session.getDispatcher();
svcRes = dispatcher.runSync("saveUpdatedCartToOrder", svcCtx);
} catch (GenericServiceException e) {
Debug.logError(e, module);
//pos.showDialog("dialog/error/exception", e.getMessage());
throw new GeneralException(ServiceUtil.getErrorMessage(svcRes));
}
}
// process the payment(s)
output.print(UtilProperties.getMessage(resource, "PosProcessing", locale));
Map<String, Object> payRes = null;
try {
payRes = (Map<String, Object>) ch.processPayment(ProductStoreWorker.getProductStore(productStoreId, session.getDelegator()), session.getUserLogin(), true);
} catch (GeneralException e) {
Debug.logError(e, module);
throw e;
}
if (payRes != null && ServiceUtil.isError(payRes)) {
throw new GeneralException(ServiceUtil.getErrorMessage(payRes));
}
// get the change due
BigDecimal change = grandTotal.subtract(paymentAmt);
// notify the change due
output.print(UtilProperties.getMessage(resource, "PosChange",locale) + " " + UtilFormatOut.formatPrice(this.getTotalDue().negate()));
// threaded drawer/receipt printing
final PosTransaction currentTrans = this;
final SwingWorker worker = new SwingWorker() {
@Override
public Object construct() {
// open the drawer
currentTrans.popDrawer();
// print the receipt
DeviceLoader.receipt.printReceipt(currentTrans, true);
return null;
}
};
worker.start();
// save the TX Log
txLog.set("statusId", "POSTX_SOLD");
txLog.set("orderId", orderId);
txLog.set("itemCount", new Long(cart.size()));
txLog.set("logEndDateTime", UtilDateTime.nowTimestamp());
try {
txLog.store();
} catch (GenericEntityException e) {
Debug.logError(e, "Unable to store TX log - not fatal", module);
}
// clear the tx
currentTx = null;
partyId = "_NA_";
return change;
}
private synchronized GenericValue getStoreOrgAddress() {
if (this.shipAddress == null) {
// locate the store's physical address - use this for tax
GenericValue facility = (GenericValue) session.getAttribute("facility");
if (facility == null) {
return null;
}
Delegator delegator = session.getDelegator();
GenericValue facilityContactMech = ContactMechWorker.getFacilityContactMechByPurpose(delegator, facilityId, UtilMisc.toList("SHIP_ORIG_LOCATION", "PRIMARY_LOCATION"));
if (facilityContactMech != null) {
try {
this.shipAddress = session.getDelegator().findByPrimaryKey("PostalAddress",
UtilMisc.toMap("contactMechId", facilityContactMech.getString("contactMechId")));
} catch (GenericEntityException e) {
Debug.logError(e, module);
}
}
}
return this.shipAddress;
}
public void saveTx() {
savedTx.push(this);
currentTx = null;
trace("transaction saved");
}
public void appendItemDataModel(XModel model) {
if (cart != null) {
Iterator<?> i = cart.iterator();
while (i.hasNext()) {
ShoppingCartItem item = (ShoppingCartItem) i.next();
BigDecimal quantity = item.getQuantity();
BigDecimal unitPrice = item.getBasePrice();
BigDecimal subTotal = unitPrice.multiply(quantity);
BigDecimal adjustment = item.getOtherAdjustments();
XModel line = Journal.appendNode(model, "tr", ""+cart.getItemIndex(item), "");
Journal.appendNode(line, "td", "sku", item.getProductId());
Journal.appendNode(line, "td", "desc", item.getName());
Journal.appendNode(line, "td", "qty", UtilFormatOut.formatQuantity(quantity));
Journal.appendNode(line, "td", "price", UtilFormatOut.formatPrice(subTotal));
Journal.appendNode(line, "td", "index", Integer.toString(cart.getItemIndex(item)));
if (this.isAggregatedItem(item.getProductId())) {
// put alterations here
ProductConfigWrapper pcw = null;
// product = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", productId));
// pcw = new ProductConfigWrapper(delegator, session.getDispatcher(), productId, null, null, null, null, null, null);
pcw = item.getConfigWrapper();
List<ConfigOption> selected = pcw.getSelectedOptions();
for (ConfigOption configoption : selected) {
if (configoption.isSelected()) {
XModel option = Journal.appendNode(model, "tr", ""+cart.getItemIndex(item), "");
Journal.appendNode(option, "td", "sku", "");
Journal.appendNode(option, "td", "desc", configoption.getDescription());
Journal.appendNode(option, "td", "qty", "");
Journal.appendNode(option, "td", "price", UtilFormatOut.formatPrice(configoption.getPrice()));
Journal.appendNode(option, "td", "index", Integer.toString(cart.getItemIndex(item)));
}
}
}
if (adjustment.compareTo(BigDecimal.ZERO) != 0) {
// append the promo info
XModel promo = Journal.appendNode(model, "tr", "itemadjustment", "");
Journal.appendNode(promo, "td", "sku", "");
Journal.appendNode(promo, "td", "desc", UtilProperties.getMessage(resource, "PosItemDiscount", locale));
Journal.appendNode(promo, "td", "qty", "");
Journal.appendNode(promo, "td", "price", UtilFormatOut.formatPrice(adjustment));
}
}
}
}
public void appendTotalDataModel(XModel model) {
if (cart != null) {
BigDecimal taxAmount = cart.getTotalSalesTax();
BigDecimal total = cart.getGrandTotal();
List<GenericValue> adjustments = cart.getAdjustments();
BigDecimal itemsAdjustmentsAmount = BigDecimal.ZERO;
Iterator<?> i = cart.iterator();
while (i.hasNext()) {
ShoppingCartItem item = (ShoppingCartItem) i.next();
BigDecimal adjustment = item.getOtherAdjustments();
if (adjustment.compareTo(BigDecimal.ZERO) != 0) {
itemsAdjustmentsAmount = itemsAdjustmentsAmount.add(adjustment);
}
}
for (GenericValue orderAdjustment : adjustments) {
BigDecimal amount = orderAdjustment.getBigDecimal("amount");
BigDecimal sourcePercentage = orderAdjustment.getBigDecimal("sourcePercentage");
XModel adjustmentLine = Journal.appendNode(model, "tr", "adjustment", "");
Journal.appendNode(adjustmentLine, "td", "sku", "");
Journal.appendNode(adjustmentLine, "td", "desc",
UtilProperties.getMessage(resource, "PosSalesDiscount", locale));
if (UtilValidate.isNotEmpty(amount)) {
Journal.appendNode(adjustmentLine, "td", "qty", "");
Journal.appendNode(adjustmentLine, "td", "price", UtilFormatOut.formatPrice(amount));
} else if (UtilValidate.isNotEmpty(sourcePercentage)) {
BigDecimal percentage = sourcePercentage.movePointLeft(2).negate(); // sourcePercentage is negative and must be show as a positive value (it's a discount not an amount)
Journal.appendNode(adjustmentLine, "td", "qty", UtilFormatOut.formatPercentage(percentage));
amount = cart.getItemTotal().add(itemsAdjustmentsAmount).multiply(percentage); // itemsAdjustmentsAmount is negative
Journal.appendNode(adjustmentLine, "td", "price", UtilFormatOut.formatPrice(amount.negate())); // amount must be shown as a negative value
}
Journal.appendNode(adjustmentLine, "td", "index", "-1");
}
XModel taxLine = Journal.appendNode(model, "tr", "tax", "");
Journal.appendNode(taxLine, "td", "sku", "");
Journal.appendNode(taxLine, "td", "desc", UtilProperties.getMessage(resource, "PosSalesTax", locale));
Journal.appendNode(taxLine, "td", "qty", "");
Journal.appendNode(taxLine, "td", "price", UtilFormatOut.formatPrice(taxAmount));
Journal.appendNode(taxLine, "td", "index", "-1");
XModel totalLine = Journal.appendNode(model, "tr", "total", "");
Journal.appendNode(totalLine, "td", "sku", "");
Journal.appendNode(totalLine, "td", "desc", UtilProperties.getMessage(resource, "PosGrandTotal", locale));
Journal.appendNode(totalLine, "td", "qty", "");
Journal.appendNode(totalLine, "td", "price", UtilFormatOut.formatPrice(total));
Journal.appendNode(totalLine, "td", "index", "-1");
}
}
public void appendPaymentDataModel(XModel model) {
if (cart != null) {
int paymentInfoSize = cart.selectedPayments();
for (int i = 0; i < paymentInfoSize; i++) {
ShoppingCart.CartPaymentInfo inf = cart.getPaymentInfo(i);
GenericValue paymentInfoObj = inf.getValueObject(session.getDelegator());
GenericValue paymentMethodType = null;
GenericValue paymentMethod = null;
if ("PaymentMethod".equals(paymentInfoObj.getEntityName())) {
paymentMethod = paymentInfoObj;
try {
paymentMethodType = paymentMethod.getRelatedOne("PaymentMethodType");
} catch (GenericEntityException e) {
Debug.logError(e, module);
}
} else {
paymentMethodType = paymentInfoObj;
}
Object desc = paymentMethodType != null ? paymentMethodType.get("description",locale) : "??";
String descString = desc.toString();
BigDecimal amount = BigDecimal.ZERO;
if (inf.amount == null) {
amount = cart.getGrandTotal().subtract(cart.getPaymentTotal());
} else {
amount = inf.amount;
}
XModel paymentLine = Journal.appendNode(model, "tr", Integer.toString(i), "");
Journal.appendNode(paymentLine, "td", "sku", "");
Journal.appendNode(paymentLine, "td", "desc", descString);
Journal.appendNode(paymentLine, "td", "qty", "-");
Journal.appendNode(paymentLine, "td", "price", UtilFormatOut.formatPrice(amount.negate()));
Journal.appendNode(paymentLine, "td", "index", Integer.toString(i));
}
}
}
public void appendChangeDataModel(XModel model) {
if (cart != null) {
BigDecimal changeDue = this.getTotalDue().negate();
if (changeDue.compareTo(BigDecimal.ZERO) >= 0) {
XModel changeLine = Journal.appendNode(model, "tr", "", "");
Journal.appendNode(changeLine, "td", "sku", "");
Journal.appendNode(changeLine, "td", "desc", "Change");
Journal.appendNode(changeLine, "td", "qty", "-");
Journal.appendNode(changeLine, "td", "price", UtilFormatOut.formatPrice(changeDue));
}
}
}
public String makeCreditCardVo(String cardNumber, String expDate, String firstName, String lastName) {
LocalDispatcher dispatcher = session.getDispatcher();
String expMonth = expDate.substring(0, 2);
String expYear = expDate.substring(2);
// two digit year check -- may want to re-think this
if (expYear.length() == 2) {
expYear = "20" + expYear;
}
Map<String, Object> svcCtx = FastMap.newInstance();
svcCtx.put("userLogin", session.getUserLogin());
svcCtx.put("partyId", partyId);
svcCtx.put("cardNumber", cardNumber);
svcCtx.put("firstNameOnCard", firstName == null ? "" : firstName);
svcCtx.put("lastNameOnCard", lastName == null ? "" : lastName);
svcCtx.put("expMonth", expMonth);
svcCtx.put("expYear", expYear);
svcCtx.put("cardType", UtilValidate.getCardType(cardNumber));
//Debug.log("Create CC : " + svcCtx, module);
Map<String, Object> svcRes = null;
try {
svcRes = dispatcher.runSync("createCreditCard", svcCtx);
} catch (GenericServiceException e) {
Debug.logError(e, module);
return null;
}
if (ServiceUtil.isError(svcRes)) {
Debug.logError(ServiceUtil.getErrorMessage(svcRes) + " - " + svcRes, module);
return null;
} else {
return (String) svcRes.get("paymentMethodId");
}
}
public GenericValue getTerminalState() {
Delegator delegator = session.getDelegator();
List<GenericValue> states = null;
try {
states = delegator.findByAnd("PosTerminalState", UtilMisc.toMap("posTerminalId", this.getTerminalId()));
} catch (GenericEntityException e) {
Debug.logError(e, module);
}
states = EntityUtil.filterByDate(states, UtilDateTime.nowTimestamp(), "openedDate", "closedDate", true);
return EntityUtil.getFirst(states);
}
public void setPrintWriter(PrintWriter writer) {
this.trace = writer;
}
private void trace(String s) {
trace(s, null, null);
}
private void trace(String s, Throwable t) {
trace(s, null, t);
}
private void trace(String s1, String s2) {
trace(s1, s2, null);
}
private void trace(String s1, String s2, Throwable t) {
if (trace != null) {
String msg = s1;
if (UtilValidate.isNotEmpty(s2)) {
msg = msg + "(" + s2 + ")";
}
if (t != null) {
msg = msg + " : " + t.getMessage();
}
// print the trace line
trace.println("[POS @ " + terminalId + " TX:" + transactionId + "] - " + msg);
trace.flush();
}
}
public static synchronized PosTransaction getCurrentTx(XuiSession session) {
if (currentTx == null) {
if (session.getUserLogin() != null) {
currentTx = new PosTransaction(session);
}
}
return currentTx;
}
public void loadSale(PosScreen pos) {
trace("Load a sale");
List<GenericValue> shoppingLists = createShoppingLists();
if (!shoppingLists.isEmpty()) {
Map<String, String> salesMap = createSalesMap(shoppingLists);
if (!salesMap.isEmpty()) {
LoadSale loadSale = new LoadSale(salesMap, this, pos);
loadSale.openDlg();
}
else {
pos.showDialog("dialog/error/nosales");
}
} else {
pos.showDialog("dialog/error/nosales");
}
}
public void loadOrder(PosScreen pos) {
List<GenericValue> orders = findOrders();
if (!orders.isEmpty()) {
LoadSale loadSale = new LoadSale(createOrderHash(orders), this, pos);
loadSale.openDlg();
} else {
pos.showDialog("dialog/error/nosales");
}
}
private List<GenericValue> findOrders() {
LocalDispatcher dispatcher = session.getDispatcher();
Map<String, Object> svcCtx = FastMap.newInstance();
svcCtx.put("userLogin", session.getUserLogin());
svcCtx.put("partyId", partyId);
List<String> orderStatusIds = FastList.newInstance();
orderStatusIds.add("ORDER_CREATED");
svcCtx.put("orderStatusId", orderStatusIds);
svcCtx.put("viewIndex", 1);
svcCtx.put("viewSize", 25);
svcCtx.put("showAll", "Y");
Map<String, Object> svcRes = null;
try {
svcRes = dispatcher.runSync("findOrders", svcCtx);
} catch (GenericServiceException e) {
Debug.logError(e, module);
}
if (svcRes == null) {
Debug.log(UtilProperties.getMessage("EcommerceUiLabels", "EcommerceNoShoppingListsCreate", locale), module);
} else if (ServiceUtil.isError(svcRes)) {
Debug.logError(ServiceUtil.getErrorMessage(svcRes) + " - " + svcRes, module);
} else{
Integer orderListSize = (Integer) svcRes.get("orderListSize");
if (orderListSize > 0) {
List<GenericValue> orderList = (List<GenericValue>) svcRes.get("orderList");
return orderList;
}
}
return null;
}
/* public void configureItem(String cartIndex, PosScreen pos) {
trace("configure item", cartIndex);
try {
int index = Integer.parseInt(cartIndex);
ShoppingCartItem product = cart.findCartItem(index);
Delegator delegator = cart.getDelegator();
ProductConfigWrapper pcw = null;
pcw = product.getConfigWrapper();
if (pcw != null) {
ConfigureItem configItem = new ConfigureItem(cartIndex, pcw, this, pos);
configItem.openDlg();
}
else {
pos.showDialog("dialog/error/itemnotconfigurable");
}
} catch (Exception e) {
trace("general exception", e);
Debug.logError(e, module);
}
} */
public List<GenericValue> createShoppingLists() {
List<GenericValue> shoppingLists = null;
Delegator delegator = this.session.getDelegator();
try {
shoppingLists = delegator.findList("ShoppingList", null, null, null, null, false);
} catch (GenericEntityException e) {
Debug.logError(e, module);
ServiceUtil.returnError("Error running initLowLevelCode: " + e.getMessage());
}
if (shoppingLists == null) {
Debug.log(UtilProperties.getMessage("EcommerceUiLabels", "EcommerceNoShoppingListsCreate", locale), module);
}
return shoppingLists;
}
public Map<String, String> createSalesMap(List<GenericValue> shoppingLists) {
Map<String, String> salesMap = FastMap.newInstance();
for (GenericValue shoppingList : shoppingLists) {
List<GenericValue> items = null;
try {
items = shoppingList.getRelated("ShoppingListItem", UtilMisc.toList("shoppingListItemSeqId"));
} catch (GenericEntityException e) {
Debug.logError(e, module);
}
if (UtilValidate.isNotEmpty(items)) {
String listName = shoppingList.getString("listName");
String shoppingListId = shoppingList.getString("shoppingListId");
salesMap.put(shoppingListId, listName);
}
}
return salesMap;
}
public Map<String, String> createOrderHash(List<GenericValue> orders) {
Map<String, String> hash = FastMap.newInstance();
for (GenericValue order : orders) {
String orderName = order.getString("orderName");
String orderId = order.getString("orderId");
if (orderName != null) {
hash.put(orderId, orderName);
}
}
return hash;
}
public boolean addListToCart(String shoppingListId, PosScreen pos, boolean append) {
trace("Add list to cart");
Delegator delegator = session.getDelegator();
LocalDispatcher dispatcher = session.getDispatcher();
String includeChild = null; // Perhaps will be used later ...
String prodCatalogId = null;
try {
ShoppingListEvents.addListToCart(delegator, dispatcher, cart, prodCatalogId, shoppingListId, (includeChild != null), true, append);
} catch (IllegalArgumentException e) {
Debug.logError(e, module);
pos.showDialog("dialog/error/exception", e.getMessage());
return false;
}
return true;
}
public boolean restoreOrder(String orderId, PosScreen pos, boolean append) {
trace("Restore an order");
Delegator delegator = session.getDelegator();
LocalDispatcher dispatcher = session.getDispatcher();
Map<String, Object> svcCtx = FastMap.newInstance();
svcCtx.put("userLogin", session.getUserLogin());
svcCtx.put("orderId", orderId);
svcCtx.put("skipInventoryChecks", Boolean.TRUE);
svcCtx.put("skipProductChecks", Boolean.TRUE);
Map<String, Object> svcRes = null;
try {
svcRes = dispatcher.runSync("loadCartFromOrder", svcCtx);
} catch (GenericServiceException e) {
Debug.logError(e, module);
pos.showDialog("dialog/error/exception", e.getMessage());
}
if (svcRes == null) {
Debug.log(UtilProperties.getMessage("EcommerceUiLabels", "EcommerceNoShoppingListsCreate", locale), module);
} else if (ServiceUtil.isError(svcRes)) {
Debug.logError(ServiceUtil.getErrorMessage(svcRes) + " - " + svcRes, module);
} else{
ShoppingCart restoredCart = (ShoppingCart) svcRes.get("shoppingCart");
if (append) {
// TODO: add stuff to append items
this.cart = restoredCart;
this.orderId = orderId;
} else {
this.cart = restoredCart;
this.orderId = orderId;
}
this.ch = new CheckOutHelper(session.getDispatcher(), session.getDelegator(), cart);
if (session.getUserLogin() != null) {
cart.addAdditionalPartyRole(session.getUserLogin().getString("partyId"), "SALES_REP");
}
cart.setFacilityId(facilityId);
cart.setTerminalId(terminalId);
cart.setOrderId(orderId);
return true;
}
return false;
}
public boolean clearList(String shoppingListId, PosScreen pos) {
Delegator delegator = session.getDelegator();
try {
ShoppingListEvents.clearListInfo(delegator, shoppingListId);
} catch (GenericEntityException e) {
Debug.logError(e, module);
pos.showDialog("dialog/error/exception", e.getMessage());
return false;
}
return true;
}
public void clientProfile(PosScreen pos) {
ClientProfile clientProfile = new ClientProfile(this, pos);
clientProfile.openDlg();
}
public void saveSale(PosScreen pos) {
SaveSale saveSale = new SaveSale(this, pos);
saveSale.openDlg();
}
public void saveOrder(String shoppingListName, PosScreen pos) {
trace("Save an order");
if (cart.size() == 0) {
pos.showDialog("dialog/error/exception", UtilProperties.getMessage("OrderErrorUiLabels", "OrderUnableToCreateNewShoppingList", locale));
return;
}
Delegator delegator = this.session.getDelegator();
LocalDispatcher dispatcher = session.getDispatcher();
GenericValue userLogin = session.getUserLogin();
String shoppingListId = null;
if (!UtilValidate.isEmpty(shoppingListName)) {
// attach the party ID to the cart
cart.setOrderPartyId(partyId);
cart.setOrderName(shoppingListName);
//cart.setExternalId(shoppingListName);
//cart.setInternalCode("Internal Code");
//ch.setCheckOutOptions(null, null, null, null, null, "shipping instructions", null, null, null, "InternalId", null, null, null);
Map<String, Object> orderRes = ch.createOrder(session.getUserLogin());
if (orderRes != null && ServiceUtil.isError(orderRes)) {
Debug.logError(ServiceUtil.getErrorMessage(orderRes), module);
//throw new GeneralException(ServiceUtil.getErrorMessage(orderRes));
} else if (orderRes != null) {
this.orderId = (String) orderRes.get("orderId");
}
}
}
public void saveSale(String shoppingListName, PosScreen pos) {
trace("Save a sale");
if (cart.size() == 0) {
pos.showDialog("dialog/error/exception", UtilProperties.getMessage("OrderErrorUiLabels", "OrderUnableToCreateNewShoppingList", locale));
return;
}
Delegator delegator = this.session.getDelegator();
LocalDispatcher dispatcher = session.getDispatcher();
GenericValue userLogin = session.getUserLogin();
String shoppingListId = null;
if (!UtilValidate.isEmpty(shoppingListName)) {
// create a new shopping list with partyId = user connected (POS clerk, etc.) and not buyer (_NA_ in POS)
Map<String, Object> serviceCtx = UtilMisc.toMap("userLogin", session.getUserLogin(), "partyId", session.getUserPartyId(),
"productStoreId", productStoreId, "listName", shoppingListName);
serviceCtx.put("shoppingListTypeId", "SLT_SPEC_PURP");
Map<String, Object> newListResult = null;
try {
newListResult = dispatcher.runSync("createShoppingList", serviceCtx);
} catch (GenericServiceException e) {
Debug.logError(e, "Problem while creating new ShoppingList", module);
pos.showDialog("dialog/error/exception", UtilProperties.getMessage("OrderErrorUiLabels", "OrderUnableToCreateNewShoppingList", locale));
return;
}
// check for errors
if (ServiceUtil.isError(newListResult)) {
String error = ServiceUtil.getErrorMessage(newListResult);
Debug.logError(error, module);
pos.showDialog("dialog/error/exception", error);
return;
}
// get the new list id
if (newListResult != null) {
shoppingListId = (String) newListResult.get("shoppingListId");
} else {
Debug.logError("Problem while creating new ShoppingList", module);
pos.showDialog("dialog/error/exception", UtilProperties.getMessage("OrderErrorUiLabels", "OrderUnableToCreateNewShoppingList", locale));
return;
}
}
String selectedCartItems[] = new String[cart.size()];
for(int i = 0; i < cart.size(); i++) {
Integer integer = new Integer(i);
selectedCartItems[i] = integer.toString();
}
try {
ShoppingListEvents.addBulkFromCart(delegator, dispatcher, cart, userLogin, shoppingListId, selectedCartItems, true, true);
} catch (IllegalArgumentException e) {
Debug.logError(e, "Problem while creating new ShoppingList", module);
pos.showDialog("dialog/error/exception", UtilProperties.getMessage("OrderErrorUiLabels", "OrderUnableToCreateNewShoppingList", locale));
}
}
public String addProductPromoCode(String code) {
trace("Add a promo code");
LocalDispatcher dispatcher = session.getDispatcher();
String result = cart.addProductPromoCode(code, dispatcher);
calcTax();
return result;
}
// TODO, I really wonder if there is not a better way to do this (DynamicView excluded because of the contactMechId collisions between phone and email)!
private List<Map<String, String>> searchContactMechs(Delegator delegator, PosScreen pos, List<Map<String, String>> partyList, String valueToCompare, String contactMechType) {
ListIterator<Map<String, String>> partyListIt = partyList.listIterator();
while(partyListIt.hasNext()) {
Map<String, String> party = partyListIt.next();
String partyId = party.get("partyId");
List<Map<String, Object>> partyContactMechValueMaps = ContactMechWorker.getPartyContactMechValueMaps(delegator, partyId, false, contactMechType);
Integer nb = 0;
for (Map<String, Object> partyContactMechValueMap : partyContactMechValueMaps) {
nb++;
String keyType = null;
String key = null;
if ("TELECOM_NUMBER".equals(contactMechType)) {
keyType = "telecomNumber";
key = "contactNumber";
} else if ("EMAIL_ADDRESS".equals(contactMechType)) {
keyType = "contactMech";
key = "infoString";
}
Map<String, Object> keyTypeMap = (Map<String, Object>) partyContactMechValueMap.get(keyType);
String keyTypeValue = ((String) keyTypeMap.get(key)).trim();
if (valueToCompare.equals(keyTypeValue) || UtilValidate.isEmpty(valueToCompare)) {
if (nb == 1) {
party.put(key, keyTypeValue);
partyListIt.set(party);
} else {
Map<String, String> partyClone = FastMap.newInstance();
partyClone.putAll(party);
partyClone.put(key, keyTypeValue);
partyListIt.add(partyClone);
}
}
}
}
return partyList;
}
public List<Map<String, String>> searchClientProfile(String name, String email, String phone, String card, PosScreen pos, Boolean equalsName) {
Delegator delegator = this.session.getDelegator();
List<GenericValue> partyList = null;
List<Map<String, String>> resultList = null;
// create the dynamic view entity
DynamicViewEntity dynamicView = new DynamicViewEntity();
// Person (name + card)
dynamicView.addMemberEntity("PT", "Party");
dynamicView.addAlias("PT", "partyId");
dynamicView.addAlias("PT", "statusId");
dynamicView.addAlias("PT", "partyTypeId");
dynamicView.addMemberEntity("PE", "Person");
dynamicView.addAlias("PE", "partyId");
dynamicView.addAlias("PE", "lastName");
dynamicView.addAlias("PE", "cardId");
dynamicView.addViewLink("PT", "PE", Boolean.FALSE, ModelKeyMap.makeKeyMapList("partyId"));
if (UtilValidate.isNotEmpty(email)) {
// ContactMech (email)
dynamicView.addMemberEntity("PM", "PartyContactMechPurpose");
dynamicView.addAlias("PM", "contactMechId");
dynamicView.addAlias("PM", "contactMechPurposeTypeId");
dynamicView.addAlias("PM", "thruDate");
dynamicView.addMemberEntity("CM", "ContactMech");
dynamicView.addAlias("CM", "infoString");
dynamicView.addViewLink("PT", "PM", Boolean.FALSE, ModelKeyMap.makeKeyMapList("partyId"));
dynamicView.addViewLink("PM", "CM", Boolean.FALSE, ModelKeyMap.makeKeyMapList("contactMechId"));
} else if (UtilValidate.isNotEmpty(phone)) {
dynamicView.addMemberEntity("PM", "PartyContactMechPurpose");
dynamicView.addAlias("PM", "contactMechId");
dynamicView.addAlias("PM", "thruDate");
dynamicView.addAlias("PM", "contactMechPurposeTypeId");
dynamicView.addMemberEntity("TN", "TelecomNumber");
dynamicView.addAlias("TN", "contactNumber");
dynamicView.addViewLink("PT", "PM", Boolean.FALSE, ModelKeyMap.makeKeyMapList("partyId"));
dynamicView.addViewLink("PM", "TN", Boolean.FALSE, ModelKeyMap.makeKeyMapList("contactMechId"));
}
// define the main condition & expression list
List<EntityCondition> andExprs = FastList.newInstance();
EntityCondition mainCond = null;
List<String> orderBy = FastList.newInstance();
List<String> fieldsToSelect = FastList.newInstance();
// fields we need to select; will be used to set distinct
fieldsToSelect.add("partyId");
fieldsToSelect.add("lastName");
fieldsToSelect.add("cardId");
if (UtilValidate.isNotEmpty(email)) {
fieldsToSelect.add("infoString");
} else if (UtilValidate.isNotEmpty(phone)) {
fieldsToSelect.add("contactNumber");
}
// NOTE: _must_ explicitly allow null as it is not included in a not equal in many databases... odd but true
// This allows to get all clients when any informations has been entered
andExprs.add(EntityCondition.makeCondition(EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "PARTY_DISABLED")));
andExprs.add(EntityCondition.makeCondition("partyTypeId", EntityOperator.EQUALS, "PERSON")); // Only persons for now...
if (UtilValidate.isNotEmpty(name)) {
if (equalsName) {
andExprs.add(EntityCondition.makeCondition("lastName", EntityOperator.EQUALS, name)); // Plain name
} else {
// andExprs.add(EntityCondition.makeCondition("lastName", EntityOperator.LIKE, "%"+name+"%")); // Less restrictive
andExprs.add(EntityCondition.makeCondition(EntityFunction.UPPER_FIELD("lastName"), EntityOperator.LIKE, EntityFunction.UPPER("%"+name+"%"))); // Even less restrictive
}
}
if (UtilValidate.isNotEmpty(card)) {
andExprs.add(EntityCondition.makeCondition("cardId", EntityOperator.EQUALS, card));
}
if (UtilValidate.isNotEmpty(email)) {
andExprs.add(EntityCondition.makeCondition("infoString", EntityOperator.EQUALS, email));
andExprs.add(EntityCondition.makeCondition("contactMechPurposeTypeId", EntityOperator.EQUALS, "PRIMARY_EMAIL"));
andExprs.add(EntityCondition.makeCondition("thruDate", EntityOperator.EQUALS, null));
} else if (UtilValidate.isNotEmpty(phone)) {
andExprs.add(EntityCondition.makeCondition("contactNumber", EntityOperator.EQUALS, phone));
andExprs.add(EntityCondition.makeCondition("contactMechPurposeTypeId", EntityOperator.EQUALS, "PHONE_HOME"));
andExprs.add(EntityCondition.makeCondition("thruDate", EntityOperator.EQUALS, null));
}
mainCond = EntityCondition.makeCondition(andExprs, EntityOperator.AND);
orderBy.add("lastName");
Debug.logInfo("In searchClientProfile mainCond=" + mainCond, module);
Integer maxRows = Integer.MAX_VALUE;
// attempt to start a transaction
boolean beganTransaction = false;
try {
beganTransaction = TransactionUtil.begin();
try {
// set distinct on so we only get one row per person
EntityFindOptions findOpts = new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, -1, maxRows, true);
// using list iterator
EntityListIterator pli = delegator.findListIteratorByCondition(dynamicView, mainCond, null, fieldsToSelect, orderBy, findOpts);
// get the partial list for this page
partyList = pli.getPartialList(1, maxRows);
// close the list iterator
pli.close();
} catch (GenericEntityException e) {
Debug.logError(e, module);
pos.showDialog("dialog/error/exception", e.getMessage());
}
} catch (GenericTransactionException e) {
Debug.logError(e, module);
try {
TransactionUtil.rollback(beganTransaction, e.getMessage(), e);
} catch (GenericTransactionException e2) {
Debug.logError(e2, "Unable to rollback transaction", module);
pos.showDialog("dialog/error/exception", e2.getMessage());
}
pos.showDialog("dialog/error/exception", e.getMessage());
} finally {
try {
TransactionUtil.commit(beganTransaction);
} catch (GenericTransactionException e) {
Debug.logError(e, "Unable to commit transaction", module);
pos.showDialog("dialog/error/exception", e.getMessage());
}
}
if (partyList != null) {
resultList = FastList.newInstance();
for (GenericValue party : partyList) {
Map<String, String> partyMap = FastMap.newInstance();
partyMap.put("partyId", party.getString("partyId"));
partyMap.put("lastName", party.getString("lastName"));
partyMap.put("cardId", party.getString("cardId"));
if (UtilValidate.isNotEmpty(email)) {
partyMap.put("infoString", party.getString("infoString"));
partyMap.put("contactNumber", "");
} else if (UtilValidate.isNotEmpty(phone)) {
partyMap.put("infoString", "");
partyMap.put("contactNumber", party.getString("contactNumber"));
} else { // both empty
partyMap.put("infoString", "");
partyMap.put("contactNumber", "");
}
resultList.add(partyMap);
}
if (UtilValidate.isNotEmpty(email)) {
resultList = searchContactMechs(delegator, pos, resultList, phone, "TELECOM_NUMBER");
} else if (UtilValidate.isNotEmpty(phone)) {
resultList = searchContactMechs(delegator, pos, resultList, "", "EMAIL_ADDRESS"); // "" is more clear than email which is by definition here is empty
} else { // both empty
resultList = searchContactMechs(delegator, pos, resultList, "", "TELECOM_NUMBER"); // "" is more clear than phone which is by definition here is empty
resultList = searchContactMechs(delegator, pos, resultList, "", "EMAIL_ADDRESS");
}
} else {
resultList = FastList.newInstance();
}
return resultList;
}
public String editClientProfile(String name, String email, String phone, String card, PosScreen pos, String editType, String partyId) {
// We suppose here that a cardId (card number) can only belongs to one person (it's used as owned PromoCode)
// We use the 1st party's login (it may change and be multiple since it depends on email and card)
// We suppose only one email address (should be ok anyway because of the contactMechPurposeTypeId == "PRIMARY_EMAIL")
// we suppose only one phone number (should be ok anyway because of the contactMechPurposeTypeId == "PHONE_HOME")
LocalDispatcher dispatcher = session.getDispatcher();
GenericValue userLogin = session.getUserLogin();
GenericValue partyUserLogin = null;
String result = null;
Map<String, Object> svcCtx = FastMap.newInstance();
Map<String, Object> svcRes = null;
// Create
if ("create".equals(editType)) {
trace("Create a client profile");
// createPersonAndUserLogin
trace("createPersonAndUserLogin");
if (UtilValidate.isNotEmpty(card)) {
svcCtx.put("cardId", card);
}
svcCtx.put("userLogin", userLogin);
svcCtx.put("lastName", name);
svcCtx.put("firstName", ""); // Needed by service createPersonAndUserLogin
if (UtilValidate.isNotEmpty(email) && UtilValidate.isNotEmpty(phone)) {
svcCtx.put("userLoginId", email);
svcCtx.put("currentPassword", phone);
svcCtx.put("currentPasswordVerify", phone);
try {
svcRes = dispatcher.runSync("createPersonAndUserLogin", svcCtx);
} catch (GenericServiceException e) {
Debug.logError(e, module);
pos.showDialog("dialog/error/exception", e.getMessage());
return null;
}
if (ServiceUtil.isError(svcRes)) {
pos.showDialog("dialog/error/exceptionLargeSmallFont", ServiceUtil.getErrorMessage(svcRes)); // exceptionLargeSmallFont used to show duplicate key error message for card
return null;
}
partyId = (String) svcRes.get("partyId");
partyUserLogin = (GenericValue) svcRes.get("newUserLogin");
} else {
// createPerson
trace("createPerson");
try {
svcRes = dispatcher.runSync("createPerson", svcCtx);
} catch (GenericServiceException e) {
Debug.logError(e, module);
pos.showDialog("dialog/error/exception", e.getMessage());
return result;
}
if (ServiceUtil.isError(svcRes)) {
pos.showDialog("dialog/error/exception", ServiceUtil.getErrorMessage(svcRes));
return result;
}
partyId = (String) svcRes.get("partyId");
partyUserLogin = userLogin;
}
if (UtilValidate.isNotEmpty(email)) {
// createPartyEmailAddress
trace("createPartyEmailAddress");
svcCtx.clear();
svcCtx.put("userLogin", partyUserLogin);
svcCtx.put("emailAddress", email);
svcCtx.put("partyId", partyId);
svcCtx.put("contactMechPurposeTypeId", "PRIMARY_EMAIL");
try {
svcRes = dispatcher.runSync("createPartyEmailAddress", svcCtx);
} catch (GenericServiceException e) {
Debug.logError(e, module);
pos.showDialog("dialog/error/exception", e.getMessage());
return null;
}
if (ServiceUtil.isError(svcRes)) {
pos.showDialog("dialog/error/exception", ServiceUtil.getErrorMessage(svcRes));
return null;
}
}
if (UtilValidate.isNotEmpty(phone)) {
if (phone.length() < 5 ) {
pos.showDialog("dialog/error/exception", UtilProperties.getMessage(PosTransaction.resource, "PosPhoneField5Required", locale));
} else {
// createPartyTelecomNumber
trace("createPartyTelecomNumber");
svcCtx.clear();
svcCtx.put("userLogin", partyUserLogin);
svcCtx.put("contactNumber", phone);
svcCtx.put("partyId", partyId);
svcCtx.put("contactMechPurposeTypeId", "PHONE_HOME");
try {
svcRes = dispatcher.runSync("createPartyTelecomNumber", svcCtx);
} catch (GenericServiceException e) {
Debug.logError(e, module);
pos.showDialog("dialog/error/exception", e.getMessage());
return null;
}
if (ServiceUtil.isError(svcRes)) {
pos.showDialog("dialog/error/exception", ServiceUtil.getErrorMessage(svcRes));
return null;
}
}
}
result = partyId;
// Update
} else if (UtilValidate.isNotEmpty(partyId)){
trace("Update a client profile");
GenericValue person = null;
try {
person = session.getDelegator().findByPrimaryKey("Person", UtilMisc.toMap("partyId", partyId));
} catch (GenericEntityException e) {
Debug.logError(e, module);
pos.showDialog("dialog/error/exception", e.getMessage());
return null;
}
Boolean newLogin = true;
try {
List<GenericValue> userLogins = session.getDelegator().findByAnd("UserLogin", UtilMisc.toMap("partyId", partyId));
if (UtilValidate.isNotEmpty(userLogins)) {
userLogin = userLogins.get(0);
newLogin = false;
}
} catch (GenericEntityException e) {
Debug.logError(e, module);
pos.showDialog("dialog/error/exception", e.getMessage());
return null;
}
if (!person.getString("lastName").equals(name)
|| UtilValidate.isNotEmpty(card) && !card.equals(person.getString("cardId"))) {
// Update name and possibly card (cardId)
svcCtx.put("userLogin", userLogin);
svcCtx.put("partyId", partyId);
svcCtx.put("firstName", ""); // Needed by service updatePerson
svcCtx.put("lastName", name);
if (UtilValidate.isNotEmpty(card)) {
svcCtx.put("cardId", card);
}
try {
// updatePerson
trace("updatePerson");
svcRes = dispatcher.runSync("updatePerson", svcCtx);
} catch (GenericServiceException e) {
Debug.logError(e, module);
pos.showDialog("dialog/error/exception", e.getMessage());
return null;
}
if (ServiceUtil.isError(svcRes)) {
pos.showDialog("dialog/error/exceptionLargeSmallFont", ServiceUtil.getErrorMessage(svcRes));
return null;
}
}
if (UtilValidate.isNotEmpty(phone)) {
// Create or update phone
if (phone.length() < 5 ) {
pos.showDialog("dialog/error/exception", UtilProperties.getMessage(PosTransaction.resource, "PosPhoneField5Required", locale));
} else {
String contactNumber = null;
String contactMechId = null;
svcCtx.clear();
svcCtx.put("partyId", partyId);
svcCtx.put("thruDate", null); // last one
try {
List<GenericValue> PartyTelecomNumbers = session.getDelegator().findByAnd("PartyAndTelecomNumber", svcCtx);
if (UtilValidate.isNotEmpty(PartyTelecomNumbers)) {
GenericValue PartyTelecomNumber = PartyTelecomNumbers.get(0); // There is only one phone number (contactMechPurposeTypeId == "PHONE_HOME")
contactNumber = PartyTelecomNumber.getString("contactNumber");
contactMechId = PartyTelecomNumber.getString("contactMechId");
}
} catch (GenericEntityException e) {
Debug.logError(e, module);
pos.showDialog("dialog/error/exception", e.getMessage());
return null;
}
// Create or update phone
trace("createUpdatePartyTelecomNumber");
svcCtx.remove("thruDate");
svcCtx.put("userLogin", userLogin);
svcCtx.put("contactNumber", phone);
svcCtx.put("contactMechPurposeTypeId", "PHONE_HOME");
if (UtilValidate.isNotEmpty(contactMechId)) {
svcCtx.put("contactMechId", contactMechId);
}
try {
svcRes = dispatcher.runSync("createUpdatePartyTelecomNumber", svcCtx);
} catch (GenericServiceException e) {
Debug.logError(e, module);
pos.showDialog("dialog/error/exception", e.getMessage());
return null;
}
if (ServiceUtil.isError(svcRes)) {
pos.showDialog("dialog/error/exception", ServiceUtil.getErrorMessage(svcRes));
return null;
}
// Handle login aspect where phone is taken as pwd
if (UtilValidate.isNotEmpty(contactNumber) && !phone.equals(contactNumber)) {
if (!newLogin) { // to create a new login we need also an email address
// Update password, we need to temporary set password.accept.encrypted.and.plain to "true"
// This is done only for the properties loaded for the session in memory (we don't persist the value)
trace("updatePassword");
String passwordAcceptEncryptedAndPlain = null;
try {
passwordAcceptEncryptedAndPlain = UtilProperties.getPropertyValue("security.properties", "password.accept.encrypted.and.plain");
UtilProperties.setPropertyValueInMemory("security.properties", "password.accept.encrypted.and.plain", "true");
svcRes = dispatcher.runSync("updatePassword",
UtilMisc.toMap("userLogin", userLogin,
"userLoginId", userLogin.getString("userLoginId"),
"currentPassword", userLogin.getString("currentPassword"),
"newPassword", phone,
"newPasswordVerify", phone));
} catch (GenericServiceException e) {
Debug.logError(e, "Error calling updatePassword service", module);
pos.showDialog("dialog/error/exception", e.getMessage());
UtilProperties.setPropertyValueInMemory("security.properties", "password.accept.encrypted.and.plain", passwordAcceptEncryptedAndPlain);
return null;
} finally {
// Put back passwordAcceptEncryptedAndPlain value in memory
UtilProperties.setPropertyValueInMemory("security.properties", "password.accept.encrypted.and.plain", passwordAcceptEncryptedAndPlain);
}
if (ServiceUtil.isError(svcRes)) {
pos.showDialog("dialog/error/exception", ServiceUtil.getErrorMessage(svcRes));
return null;
}
}
}
}
}
if (UtilValidate.isNotEmpty(email)) {
// Update email
svcCtx.clear();
svcCtx.put("partyId", partyId);
svcCtx.put("thruDate", null); // last one
svcCtx.put("contactMechTypeId", "EMAIL_ADDRESS");
String contactMechId = null;
String infoString = null;
try {
List<GenericValue> PartyEmails = session.getDelegator().findByAnd("PartyAndContactMech", svcCtx);
if (UtilValidate.isNotEmpty(PartyEmails)) {
GenericValue PartyEmail = PartyEmails.get(0); // There is only one email address (contactMechPurposeTypeId == "PRIMARY_EMAIL")
contactMechId = PartyEmail.getString("contactMechId");
infoString = PartyEmail.getString("infoString");
}
} catch (GenericEntityException e) {
Debug.logError(e, module);
pos.showDialog("dialog/error/exception", e.getMessage());
return null;
}
svcCtx.remove("thruDate");
svcCtx.remove("contactMechTypeId");
svcCtx.put("userLogin", userLogin);
svcCtx.put("emailAddress", email);
svcCtx.put("contactMechPurposeTypeId", "PRIMARY_EMAIL");
if (UtilValidate.isNotEmpty(contactMechId)) {
svcCtx.put("contactMechId", contactMechId);
}
if (UtilValidate.isNotEmpty(infoString) && !email.equals(infoString)
|| UtilValidate.isEmpty(infoString)) {
// Create or update email
trace("createUpdatePartyEmailAddress");
try {
svcRes = dispatcher.runSync("createUpdatePartyEmailAddress", svcCtx);
} catch (GenericServiceException e) {
Debug.logError(e, module);
pos.showDialog("dialog/error/exception", e.getMessage());
return null;
}
if (ServiceUtil.isError(svcRes)) {
pos.showDialog("dialog/error/exception", ServiceUtil.getErrorMessage(svcRes));
return null;
}
}
if (!newLogin && UtilValidate.isNotEmpty(infoString) && !email.equals(infoString)) {
// create a new UserLogin (Update a UserLoginId by creating a new one and expiring the old one). Keep the same password possibly changed just above if phone has also changed.
trace("updateUserLoginId");
try {
svcRes = dispatcher.runSync("updateUserLoginId", UtilMisc.toMap("userLoginId", email, "userLogin", userLogin));
} catch (GenericServiceException e) {
Debug.logError(e, module);
pos.showDialog("dialog/error/exception", e.getMessage());
return null;
}
if (ServiceUtil.isError(svcRes)) {
pos.showDialog("dialog/error/exception", ServiceUtil.getErrorMessage(svcRes));
return null;
}
} else if (newLogin && UtilValidate.isNotEmpty(phone)) {
// createUserLogin
trace("createUserLogin");
try {
svcRes = dispatcher.runSync("createUserLogin",
UtilMisc.toMap("userLogin", userLogin,
"userLoginId", email,
"currentPassword", phone,
"currentPasswordVerify", phone,
"partyId", partyId));
} catch (GenericServiceException e) {
Debug.logError(e, "Error calling updatePassword service", module);
pos.showDialog("dialog/error/exception", e.getMessage());
return null;
}
if (ServiceUtil.isError(svcRes)) {
pos.showDialog("dialog/error/exception", ServiceUtil.getErrorMessage(svcRes));
return null;
}
}
}
} else {
pos.showDialog("dialog/error/exception", UtilProperties.getMessage(resource, "PosNoClientProfile", locale));
return null;
}
return null;
}
}