}
/** Service for checking and re-calc the tax amount */
public static Map<String, Object> recalcOrderTax(DispatchContext ctx, Map<String, ? extends Object> context) {
LocalDispatcher dispatcher = ctx.getDispatcher();
Delegator delegator = ctx.getDelegator();
String orderId = (String) context.get("orderId");
GenericValue userLogin = (GenericValue) context.get("userLogin");
Locale locale = (Locale) context.get("locale");
// check and make sure we have permission to change the order
Security security = ctx.getSecurity();
boolean hasPermission = OrderServices.hasPermission(orderId, userLogin, "UPDATE", security, delegator);
if (!hasPermission) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,
"OrderYouDoNotHavePermissionToChangeThisOrdersStatus",locale));
}
// get the order header
GenericValue orderHeader = null;
try {
orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId));
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,
"OrderErrorCannotGetOrderHeaderEntity",locale) + e.getMessage());
}
if (orderHeader == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,
"OrderErrorNoValidOrderHeaderFoundForOrderId", UtilMisc.toMap("orderId",orderId), locale));
}
// don't charge tax on purchase orders, better we still do.....
// if ("PURCHASE_ORDER".equals(orderHeader.getString("orderTypeId"))) {
// return ServiceUtil.returnSuccess();
// }
// Retrieve the order tax adjustments
List<GenericValue> orderTaxAdjustments = null;
try {
orderTaxAdjustments = delegator.findByAnd("OrderAdjustment", UtilMisc.toMap("orderId", orderId, "orderAdjustmentTypeId", "SALES_TAX"));
} catch (GenericEntityException e) {
Debug.logError(e, "Unable to retrieve SALES_TAX adjustments for order : " + orderId, module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,
"OrderUnableToRetrieveSalesTaxAdjustments",locale));
}
// Accumulate the total existing tax adjustment
BigDecimal totalExistingOrderTax = ZERO;
Iterator<GenericValue> otait = UtilMisc.toIterator(orderTaxAdjustments);
while (otait != null && otait.hasNext()) {
GenericValue orderTaxAdjustment = otait.next();
if (orderTaxAdjustment.get("amount") != null) {
totalExistingOrderTax = totalExistingOrderTax.add(orderTaxAdjustment.getBigDecimal("amount").setScale(taxDecimals, taxRounding));
}
}
// Recalculate the taxes for the order
BigDecimal totalNewOrderTax = ZERO;
OrderReadHelper orh = new OrderReadHelper(orderHeader);
List<GenericValue> shipGroups = orh.getOrderItemShipGroups();
if (shipGroups != null) {
Iterator<GenericValue> itr = shipGroups.iterator();
while (itr.hasNext()) {
GenericValue shipGroup = itr.next();
String shipGroupSeqId = shipGroup.getString("shipGroupSeqId");
List<GenericValue> validOrderItems = orh.getValidOrderItems(shipGroupSeqId);
if (validOrderItems != null) {
// prepare the inital lists
List<GenericValue> products = new ArrayList<GenericValue>(validOrderItems.size());
List<BigDecimal> amounts = new ArrayList<BigDecimal>(validOrderItems.size());
List<BigDecimal> shipAmts = new ArrayList<BigDecimal>(validOrderItems.size());
List<BigDecimal> itPrices = new ArrayList<BigDecimal>(validOrderItems.size());
List<BigDecimal> itQuantities = new ArrayList<BigDecimal>(validOrderItems.size());
// adjustments and total
List<GenericValue> allAdjustments = orh.getAdjustments();
List<GenericValue> orderHeaderAdjustments = OrderReadHelper.getOrderHeaderAdjustments(allAdjustments, shipGroupSeqId);
BigDecimal orderSubTotal = OrderReadHelper.getOrderItemsSubTotal(validOrderItems, allAdjustments);
// shipping amount
BigDecimal orderShipping = OrderReadHelper.calcOrderAdjustments(orderHeaderAdjustments, orderSubTotal, false, false, true);
//promotions amount
BigDecimal orderPromotions = OrderReadHelper.calcOrderPromoAdjustmentsBd(allAdjustments);
// build up the list of tax calc service parameters
for (int i = 0; i < validOrderItems.size(); i++) {
GenericValue orderItem = validOrderItems.get(i);
String productId = orderItem.getString("productId");
try {
products.add(i, delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId", productId))); // get the product entity
amounts.add(i, OrderReadHelper.getOrderItemSubTotal(orderItem, allAdjustments, true, false)); // get the item amount
shipAmts.add(i, OrderReadHelper.getOrderItemAdjustmentsTotal(orderItem, allAdjustments, false, false, true)); // get the shipping amount
itPrices.add(i, orderItem.getBigDecimal("unitPrice"));
itQuantities.add(i, orderItem.getBigDecimal("quantity"));
} catch (GenericEntityException e) {
Debug.logError(e, "Cannot read order item entity : " + orderItem, module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,
"OrderCannotReadTheOrderItemEntity",locale));
}
}
GenericValue shippingAddress = orh.getShippingAddress(shipGroupSeqId);
// no shipping address, try the billing address
if (shippingAddress == null) {
List<GenericValue> billingAddressList = orh.getBillingLocations();
if (billingAddressList.size() > 0) {
shippingAddress = billingAddressList.get(0);
}
}
// TODO and NOTE DEJ20070816: this is NOT a good way to determine if this is a face-to-face or immediatelyFulfilled order
//this should be made consistent with the CheckOutHelper.makeTaxContext(int shipGroup, GenericValue shipAddress) method
if (shippingAddress == null) {
// face-to-face order; use the facility address
String facilityId = orderHeader.getString("originFacilityId");
if (facilityId != null) {
GenericValue facilityContactMech = ContactMechWorker.getFacilityContactMechByPurpose(delegator, facilityId, UtilMisc.toList("SHIP_ORIG_LOCATION", "PRIMARY_LOCATION"));
if (facilityContactMech != null) {
try {
shippingAddress = delegator.findByPrimaryKey("PostalAddress",
UtilMisc.toMap("contactMechId", facilityContactMech.getString("contactMechId")));
} catch (GenericEntityException e) {
Debug.logError(e, module);
}
}