/** * Create and return an OrderTotal object for the tax amount. * * @param order * @param dispPriceWithTax * @param locale * @return Returns an OrderTotal object for this module * @throws Exception */ public OrderTotal getOrderTotal(Order order, boolean dispPriceWithTax, Locale locale) throws Exception { OrderTotal ot; StaticData sd = staticDataHM.get(getStoreId()); // Get the resource bundle ResourceBundle rb = getResourceBundle(mutex, bundleName, resourceBundleMap, locale); if (rb == null) { throw new KKException( "A resource file cannot be found for the country " + locale.getCountry()); } ot = new OrderTotal(); ot.setSortOrder(sd.getSortOrder()); ot.setClassName(code); // Call the TaxCloud service callTaxCloud(sd, order, ot); // Set the title of the order total StringBuffer title = new StringBuffer(); title.append(rb.getString(MODULE_ORDER_TOTAL_TAX_CLOUD_TITLE)); title.append(":"); ot.setTitle(title.toString()); return ot; }
/** * Create and return an OrderTotal object for the shipping cost. * * @param order * @param dispPriceWithTax * @param locale * @return Returns an OrderTotal object for this module * @throws Exception */ public OrderTotal getOrderTotal(Order order, boolean dispPriceWithTax, Locale locale) throws Exception { OrderTotal ot; StaticData sd = staticDataHM.get(getStoreId()); // Get the resource bundle ResourceBundle rb = getResourceBundle(mutex, bundleName, resourceBundleMap, locale); if (rb == null) { throw new KKException( "A resource file cannot be found for the country " + locale.getCountry()); } ot = new OrderTotal(); ot.setSortOrder(sd.getSortOrder()); ot.setClassName(code); if (order.getShippingQuote() == null) { ot.setTitle(rb.getString(MODULE_ORDER_TOTAL_SHIPPING_TITLE) + ":"); ot.setValue(new BigDecimal(0)); ot.setText(getCurrMgr().formatPrice(new BigDecimal(0), order.getCurrencyCode())); } else { ot.setTitle( order.getShippingQuote().getTitle() + " (" + order.getShippingQuote().getResponseText() + "):"); BigDecimal cost; if (dispPriceWithTax) { cost = order.getShippingQuote().getTotalIncTax(); } else { cost = order.getShippingQuote().getTotalExTax(); } ot.setValue(cost); ot.setText(getCurrMgr().formatPrice(cost, order.getCurrencyCode())); } return ot; }
/** * Call the TaxCloud tax service which calculates the total tax for the order (including shipping) * and populates the Order Total and Order objects with the tax information. * * @param sd * @param order * @param ot * @throws Exception * @throws DataSetException * @throws TorqueException */ private void callTaxCloud(StaticData sd, Order order, OrderTotal ot) throws TorqueException, DataSetException, Exception { // Look up tax rates from TaxCloud LookupService lookupService = new LookupService(); String apiLoginID = sd.getLoginId(); String apiKey = sd.getLoginKey(); String customerId = String.valueOf(order.getCustomerId()); String cartId = order.getLifecycleId(); // Figure out whether there is a shipping charge boolean isShipping = false; ShippingQuoteIf shippingQuote = order.getShippingQuote(); if (shippingQuote != null && shippingQuote.getTotalExTax() != null && shippingQuote.getTotalExTax().compareTo(new BigDecimal(0)) == 1) { isShipping = true; } /* * Create an array of cart items to send to TaxCloud. Every item needs a TIC (Taxability * Information Code) which is contained in each order product object in the TaxCode * attribute. If we need to calculate tax for shipping we make the CartItem array longer by * one. */ int arrayLength = (isShipping) ? order.getOrderProducts().length + 1 : order.getOrderProducts().length; CartItem[] cartItems = new CartItem[arrayLength]; int cartIndex = 0; for (int i = 0; i < order.getOrderProducts().length; i++) { OrderProductIf orderProduct = order.getOrderProducts()[i]; CartItem cartItem = new CartItem(); cartItem.setIndex(cartIndex); cartItem.setItemID(String.valueOf(orderProduct.getProductId())); if (orderProduct.getTaxCode() == null || orderProduct.getTaxCode().length() == 0) { throw new KKException( "The TaxClass object for the product with id = " + orderProduct.getProductId() + " does not have a TIC (Taxability Information Code) set."); } int ticID; try { ticID = Integer.parseInt(orderProduct.getTaxCode()); } catch (Exception e) { throw new KKException( "The TaxClass object for the product with id = " + orderProduct.getProductId() + " does not have a numeric TIC (Taxability Information Code) set. The value found = " + orderProduct.getTaxCode() + " is invalid."); } cartItem.setTIC(ticID); // Must call TaxCloud with final price of a single product int scale = getTaxMgr().getTaxScale(); BigDecimal singleProdPrice = (orderProduct.getFinalPriceExTax()) .divide(new BigDecimal(orderProduct.getQuantity()), scale, BigDecimal.ROUND_HALF_UP); cartItem.setPrice(singleProdPrice.floatValue()); cartItem.setQty(orderProduct.getQuantity()); cartItems[cartIndex] = cartItem; cartIndex++; } if (isShipping) { // Add shipping charges to the cart (shipping charges are taxable) CartItem cartItem = new CartItem(); cartItem.setIndex(cartIndex); cartItem.setItemID(SHIPPING_TIC_STR); cartItem.setTIC(SHIPPING_TIC); cartItem.setPrice(shippingQuote.getTotalExTax().floatValue()); cartItem.setQty(1); cartItems[cartIndex] = cartItem; } net.taxcloud.Address destination = new net.taxcloud.Address(); destination.setAddress1(order.getDeliveryStreetAddress()); destination.setAddress2(""); destination.setCity(order.getDeliveryCity()); destination.setState(order.getDeliveryState()); destination.setZip5(order.getDeliveryPostcode()); net.taxcloud.Address destinationVerified = verifyAddress(sd, destination); if (destinationVerified == null) { throw new KKException( "The destination address could not be verified using the USPS verification service probably due to a communications problem."); } validateAddress(destination, destinationVerified); // Now set the verified address back into the Order order.setDeliveryStreetAddress(destinationVerified.getAddress1()); order.setDeliveryCity(destinationVerified.getCity()); order.setDeliveryState(destinationVerified.getState()); order.setDeliveryPostcode(destinationVerified.getZip5() + "-" + destinationVerified.getZip4()); boolean deliveredBySeller = true; ExemptionCertificate exemptionCertificate = null; CartItemResponse[] cartItemsResponse = null; try { if (log.isDebugEnabled()) { StringBuffer sb = new StringBuffer(); sb.append("Calling tax cloud tax service with the following data:\n"); sb.append("apiLoginID = ").append(apiLoginID).append("\n"); sb.append("apiKey = ").append(apiKey).append("\n"); sb.append("customerId = ").append(customerId).append("\n"); sb.append("cartId = ").append(cartId).append("\n"); sb.append("Store Address:\n"); sb.append("Address1 = ").append(sd.getOriginAddr().getAddress1()).append("\n"); sb.append("Address2 = ").append(sd.getOriginAddr().getAddress2()).append("\n"); sb.append("City = ").append(sd.getOriginAddr().getCity()).append("\n"); sb.append("State = ").append(sd.getOriginAddr().getState()).append("\n"); sb.append("Zip4 = ").append(sd.getOriginAddr().getZip4()).append("\n"); sb.append("Zip5 = ").append(sd.getOriginAddr().getZip5()).append("\n"); sb.append("Delivery Address:\n"); sb.append("Address1 = ").append(destinationVerified.getAddress1()).append("\n"); sb.append("Address2 = ").append(destinationVerified.getAddress2()).append("\n"); sb.append("City = ").append(destinationVerified.getCity()).append("\n"); sb.append("State = ").append(destinationVerified.getState()).append("\n"); sb.append("Zip4 = ").append(destinationVerified.getZip4()).append("\n"); sb.append("Zip5 = ").append(destinationVerified.getZip5()).append("\n"); sb.append("CartItems:\n"); for (int i = 0; i < cartItems.length; i++) { CartItem item = cartItems[i]; sb.append("ItemID = ").append(item.getItemID()).append("\n"); sb.append("TIC = ").append(item.getTIC()).append("\n"); sb.append("Qty = ").append(item.getQty()).append("\n"); sb.append("Price = ").append(item.getPrice()).append("\n"); } log.debug(sb); } // Call TaxCloud to look up tax rates cartItemsResponse = lookupService.lookup( apiLoginID, apiKey, customerId, cartId, cartItems, sd.getOriginAddr(), destinationVerified, deliveredBySeller, exemptionCertificate); } catch (Exception e) { log.error("Problem calling TaxCloud: ", e); } if (cartItemsResponse == null || cartItemsResponse.length == 0) { throw new KKException( "TaxCloud returned an empty response from the lookupService.lookup() API call."); } if (log.isDebugEnabled()) { log.debug("Response from TaxCloud lookup:"); for (int i = 0; i < cartItemsResponse.length; i++) { CartItemResponse r = cartItemsResponse[i]; log.debug("CartItem [index=" + r.getCartItemIndex() + ", tax=" + r.getTaxAmount() + "]"); } } float taxAmount = 0; for (int i = 0; i < cartItemsResponse.length - 1; i++) { CartItemResponse cartItemResponse = cartItemsResponse[i]; taxAmount = taxAmount + cartItemResponse.getTaxAmount(); } // Now get the tax amount for the shipping charges CartItemResponse cartItemResponse = cartItemsResponse[cartItemsResponse.length - 1]; taxAmount = taxAmount + cartItemResponse.getTaxAmount(); // Set the Order Total with the total tax amount BigDecimal taxAmountBD = new BigDecimal(taxAmount); ot.setValue(taxAmountBD); ot.setText(getCurrMgr().formatPrice(taxAmountBD, order.getCurrencyCode())); // Set the order with tax information order.setTax(taxAmountBD); order.setTotalIncTax(order.getTotalExTax().add(taxAmountBD)); }