public String invoke( Event event, RequestMap requestMap, HttpServletRequest request, HttpServletResponse response) throws EventHandlerException { try { Map<String, Object> groovyContext = FastMap.newInstance(); groovyContext.put("request", request); groovyContext.put("response", response); HttpSession session = request.getSession(); groovyContext.put("session", session); groovyContext.put("dispatcher", request.getAttribute("dispatcher")); groovyContext.put("delegator", request.getAttribute("delegator")); groovyContext.put("security", request.getAttribute("security")); groovyContext.put("locale", UtilHttp.getLocale(request)); groovyContext.put("timeZone", UtilHttp.getTimeZone(request)); groovyContext.put("userLogin", session.getAttribute("userLogin")); groovyContext.put( "parameters", UtilHttp.getCombinedMap( request, UtilMisc.toSet( "delegator", "dispatcher", "security", "locale", "timeZone", "userLogin"))); Object result = GroovyUtil.runScriptAtLocation(event.path + event.invoke, groovyContext); // check the result if (result != null && !(result instanceof String)) { throw new EventHandlerException( "Event did not return a String result, it returned a " + result.getClass().getName()); } return (String) result; } catch (Exception e) { throw new EventHandlerException("Groovy Event Error", e); } }
@Override public boolean exec(MethodContext methodContext) throws MiniLangException { String entityName = entityNameFse.expandString(methodContext.getEnvMap()); boolean useCache = "true".equals(useCacheFse.expandString(methodContext.getEnvMap())); boolean useIterator = "true".equals(useIteratorFse.expandString(methodContext.getEnvMap())); List<String> orderByNames = orderByListFma.get(methodContext.getEnvMap()); Collection<String> fieldsToSelectList = fieldsToSelectListFma.get(methodContext.getEnvMap()); Delegator delegator = getDelegator(methodContext); try { EntityCondition whereCond = null; Map<String, ? extends Object> fieldMap = mapFma.get(methodContext.getEnvMap()); if (fieldMap != null) { whereCond = EntityCondition.makeCondition(fieldMap); } if (useIterator) { listFma.put( methodContext.getEnvMap(), delegator.find( entityName, whereCond, null, UtilMisc.toSet(fieldsToSelectList), orderByNames, null)); } else { listFma.put( methodContext.getEnvMap(), delegator.findList( entityName, whereCond, UtilMisc.toSet(fieldsToSelectList), orderByNames, null, useCache)); } } catch (GenericEntityException e) { String errMsg = "Exception thrown while performing entity find: " + e.getMessage(); Debug.logWarning(e, errMsg, module); simpleMethod.addErrorMessage(methodContext, errMsg); return false; } return true; }
public String invoke( Event event, RequestMap requestMap, HttpServletRequest request, HttpServletResponse response) throws EventHandlerException { if (Debug.infoOn()) { Debug.logInfo("In GwtRpcGroovyEventHandler", module); } String requestPayload = null; try { requestPayload = GwtRpcPayloadUtil.getRequestPayload(request); } catch (IOException ioe) { throw new EventHandlerException("Exception while getting requestPayload", ioe); } catch (ServletException se) { throw new EventHandlerException("Exception while getting requestPayload", se); } HashMap<String, String> gwtParameters = GwtRpcPayloadUtil.getParameters(requestPayload); if (Debug.infoOn()) { Debug.logInfo("gwtParameters : " + gwtParameters, module); } if (null != gwtParameters) { HttpSession session = request.getSession(); Map<String, Object> groovyContext = FastMap.newInstance(); groovyContext.put("request", request); groovyContext.put("response", response); groovyContext.put("session", session); groovyContext.put("dispatcher", request.getAttribute("dispatcher")); groovyContext.put("delegator", request.getAttribute("delegator")); groovyContext.put("security", request.getAttribute("security")); groovyContext.put("locale", UtilHttp.getLocale(request)); groovyContext.put("timeZone", UtilHttp.getTimeZone(request)); groovyContext.put("userLogin", session.getAttribute("userLogin")); Map<String, Object> parameters = UtilHttp.getCombinedMap( request, UtilMisc.toSet( "delegator", "dispatcher", "security", "locale", "timeZone", "userLogin")); if (Debug.infoOn()) { Debug.logInfo("parameters : " + parameters, module); } Set<String> keys = gwtParameters.keySet(); Iterator<String> iter = keys.iterator(); while (iter.hasNext()) { String key = iter.next(); parameters.put(key, gwtParameters.get(key)); } groovyContext.put("parameters", parameters); Object result = null; try { result = GroovyUtil.runScriptAtLocation(event.path + event.invoke, groovyContext); if (Debug.infoOn()) { Debug.logInfo("groovy script result : " + result, module); } } catch (GeneralException ge) { throw new EventHandlerException("Exception while executing groovy script : ", ge); } Map<String, Object> resultMap = (Map<String, Object>) result; // ServletContext sc = (ServletContext)request.getAttribute("servletContext"); // RequestDispatcher rd = sc.getRequestDispatcher("/gwtrpc"); request.setAttribute(GwtRpcPayload.OFBIZ_PAYLOAD, resultMap); request.setAttribute(GwtRpcPayload.REQUEST_PAYLOAD, requestPayload); /*try { rd.forward(request, response); } catch(IOException ioe) { throw new EventHandlerException("IO Exception while forwarding request to GWT RPC servlet : ",ioe); } catch(ServletException se) { throw new EventHandlerException("Servlet Exception while forwarding request to GWT RPC servlet : ",se); }*/ try { GwtRpcServletUtil servletUtil = new GwtRpcServletUtil(); String responsePayload = servletUtil.invokeServlet(request, response, requestPayload); servletUtil.writeResponse(servletContext, request, response, responsePayload); } catch (Exception e) { Debug.logError(e, "gwt remote servlet invocation failed " + e.getMessage(), module); throw new EventHandlerException(e); } } else { throw new EventHandlerException("GWT parameters are null : " + gwtParameters); } return "success"; }
private static List<GenericValue> getTaxAdjustments( Delegator delegator, GenericValue product, GenericValue productStore, String payToPartyId, String billToPartyId, Set<GenericValue> taxAuthoritySet, BigDecimal itemPrice, BigDecimal itemQuantity, BigDecimal itemAmount, BigDecimal shippingAmount, BigDecimal orderPromotionsAmount) { Timestamp nowTimestamp = UtilDateTime.nowTimestamp(); List<GenericValue> adjustments = FastList.newInstance(); if (payToPartyId == null) { if (productStore != null) { payToPartyId = productStore.getString("payToPartyId"); } } // store expr EntityCondition storeCond = null; if (productStore != null) { storeCond = EntityCondition.makeCondition( EntityCondition.makeCondition( "productStoreId", EntityOperator.EQUALS, productStore.get("productStoreId")), EntityOperator.OR, EntityCondition.makeCondition("productStoreId", EntityOperator.EQUALS, null)); } else { storeCond = EntityCondition.makeCondition("productStoreId", EntityOperator.EQUALS, null); } // build the TaxAuthority expressions (taxAuthGeoId, taxAuthPartyId) List<EntityCondition> taxAuthCondOrList = FastList.newInstance(); // start with the _NA_ TaxAuthority... taxAuthCondOrList.add( EntityCondition.makeCondition( EntityCondition.makeCondition("taxAuthPartyId", EntityOperator.EQUALS, "_NA_"), EntityOperator.AND, EntityCondition.makeCondition("taxAuthGeoId", EntityOperator.EQUALS, "_NA_"))); for (GenericValue taxAuthority : taxAuthoritySet) { EntityCondition taxAuthCond = EntityCondition.makeCondition( EntityCondition.makeCondition( "taxAuthPartyId", EntityOperator.EQUALS, taxAuthority.getString("taxAuthPartyId")), EntityOperator.AND, EntityCondition.makeCondition( "taxAuthGeoId", EntityOperator.EQUALS, taxAuthority.getString("taxAuthGeoId"))); taxAuthCondOrList.add(taxAuthCond); } EntityCondition taxAuthoritiesCond = EntityCondition.makeCondition(taxAuthCondOrList, EntityOperator.OR); try { EntityCondition productCategoryCond = null; if (product != null) { // find the tax categories associated with the product and filter by those, with an IN // clause or some such // if this product is variant, find the virtual product id and consider also the categories // of the virtual // question: get all categories, or just a special type? for now let's do all categories... String virtualProductId = null; if ("Y".equals(product.getString("isVariant"))) { virtualProductId = ProductWorker.getVariantVirtualId(product); } Set<String> productCategoryIdSet = FastSet.newInstance(); EntityCondition productIdCond = null; if (virtualProductId != null) { productIdCond = EntityCondition.makeCondition( EntityCondition.makeCondition( "productId", EntityOperator.EQUALS, product.getString("productId")), EntityOperator.OR, EntityCondition.makeCondition( "productId", EntityOperator.EQUALS, virtualProductId)); } else { productIdCond = EntityCondition.makeCondition( "productId", EntityOperator.EQUALS, product.getString("productId")); } List<GenericValue> pcmList = delegator.findList( "ProductCategoryMember", productIdCond, UtilMisc.toSet("productCategoryId", "fromDate", "thruDate"), null, null, true); pcmList = EntityUtil.filterByDate(pcmList, true); for (GenericValue pcm : pcmList) { productCategoryIdSet.add(pcm.getString("productCategoryId")); } if (productCategoryIdSet.size() == 0) { productCategoryCond = EntityCondition.makeCondition("productCategoryId", EntityOperator.EQUALS, null); } else { productCategoryCond = EntityCondition.makeCondition( EntityCondition.makeCondition("productCategoryId", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition( "productCategoryId", EntityOperator.IN, productCategoryIdSet)); } } else { productCategoryCond = EntityCondition.makeCondition("productCategoryId", EntityOperator.EQUALS, null); } // FIXME handles shipping and promo tax. Simple solution, see // https://issues.apache.org/jira/browse/OFBIZ-4160 for a better one if (product == null && shippingAmount != null) { EntityCondition taxShippingCond = EntityCondition.makeCondition( EntityCondition.makeCondition("taxShipping", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition("taxShipping", EntityOperator.EQUALS, "Y")); if (productCategoryCond != null) { productCategoryCond = EntityCondition.makeCondition( productCategoryCond, EntityOperator.OR, taxShippingCond); } } if (product == null && orderPromotionsAmount != null) { EntityCondition taxOrderPromotionsCond = EntityCondition.makeCondition( EntityCondition.makeCondition("taxPromotions", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition("taxPromotions", EntityOperator.EQUALS, "Y")); if (productCategoryCond != null) { productCategoryCond = EntityCondition.makeCondition( productCategoryCond, EntityOperator.OR, taxOrderPromotionsCond); } } // build the main condition clause List<EntityCondition> mainExprs = UtilMisc.toList(storeCond, taxAuthoritiesCond, productCategoryCond); mainExprs.add( EntityCondition.makeCondition( EntityCondition.makeCondition("minItemPrice", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition( "minItemPrice", EntityOperator.LESS_THAN_EQUAL_TO, itemPrice))); mainExprs.add( EntityCondition.makeCondition( EntityCondition.makeCondition("minPurchase", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition( "minPurchase", EntityOperator.LESS_THAN_EQUAL_TO, itemAmount))); EntityCondition mainCondition = EntityCondition.makeCondition(mainExprs, EntityOperator.AND); // create the orderby clause List<String> orderList = UtilMisc.<String>toList("minItemPrice", "minPurchase", "fromDate"); // finally ready... do the rate query List<GenericValue> lookupList = delegator.findList( "TaxAuthorityRateProduct", mainCondition, null, orderList, null, false); List<GenericValue> filteredList = EntityUtil.filterByDate(lookupList, true); if (filteredList.size() == 0) { Debug.logWarning( "In TaxAuthority Product Rate no records were found for condition:" + mainCondition.toString(), module); return adjustments; } // find the right entry(s) based on purchase amount for (GenericValue taxAuthorityRateProduct : filteredList) { BigDecimal taxRate = taxAuthorityRateProduct.get("taxPercentage") != null ? taxAuthorityRateProduct.getBigDecimal("taxPercentage") : ZERO_BASE; BigDecimal taxable = ZERO_BASE; if (product != null && (product.get("taxable") == null || (product.get("taxable") != null && product.getBoolean("taxable").booleanValue()))) { taxable = taxable.add(itemAmount); } if (shippingAmount != null && taxAuthorityRateProduct != null && (taxAuthorityRateProduct.get("taxShipping") == null || (taxAuthorityRateProduct.get("taxShipping") != null && taxAuthorityRateProduct.getBoolean("taxShipping").booleanValue()))) { taxable = taxable.add(shippingAmount); } if (orderPromotionsAmount != null && taxAuthorityRateProduct != null && (taxAuthorityRateProduct.get("taxPromotions") == null || (taxAuthorityRateProduct.get("taxPromotions") != null && taxAuthorityRateProduct.getBoolean("taxPromotions").booleanValue()))) { taxable = taxable.add(orderPromotionsAmount); } if (taxable.compareTo(BigDecimal.ZERO) == 0) { // this should make it less confusing if the taxable flag on the product is not Y/true, // and there is no shipping and such continue; } // taxRate is in percentage, so needs to be divided by 100 BigDecimal taxAmount = (taxable.multiply(taxRate)) .divide(PERCENT_SCALE, salestaxCalcDecimals, salestaxRounding); String taxAuthGeoId = taxAuthorityRateProduct.getString("taxAuthGeoId"); String taxAuthPartyId = taxAuthorityRateProduct.getString("taxAuthPartyId"); // get glAccountId from TaxAuthorityGlAccount entity using the payToPartyId as the // organizationPartyId GenericValue taxAuthorityGlAccount = delegator.findByPrimaryKey( "TaxAuthorityGlAccount", UtilMisc.toMap( "taxAuthPartyId", taxAuthPartyId, "taxAuthGeoId", taxAuthGeoId, "organizationPartyId", payToPartyId)); String taxAuthGlAccountId = null; if (taxAuthorityGlAccount != null) { taxAuthGlAccountId = taxAuthorityGlAccount.getString("glAccountId"); } else { // TODO: what to do if no TaxAuthorityGlAccount found? Use some default, or is that done // elsewhere later on? } GenericValue productPrice = null; if (product != null && taxAuthPartyId != null && taxAuthGeoId != null) { // find a ProductPrice for the productId and taxAuth* valxues, and see if it has a // priceWithTax value Map<String, String> priceFindMap = UtilMisc.toMap( "productId", product.getString("productId"), "taxAuthPartyId", taxAuthPartyId, "taxAuthGeoId", taxAuthGeoId, "productPricePurposeId", "PURCHASE"); List<GenericValue> productPriceList = delegator.findByAnd("ProductPrice", priceFindMap, UtilMisc.toList("-fromDate")); productPriceList = EntityUtil.filterByDate(productPriceList, true); productPrice = (productPriceList != null && productPriceList.size() > 0) ? productPriceList.get(0) : null; // Debug.logInfo("=================== productId=" + product.getString("productId"), // module); // Debug.logInfo("=================== productPrice=" + productPrice, module); } GenericValue taxAdjValue = delegator.makeValue("OrderAdjustment"); if (productPrice != null && "Y".equals(productPrice.getString("taxInPrice"))) { // tax is in the price already, so we want the adjustment to be a VAT_TAX adjustment to be // subtracted instead of a SALES_TAX adjustment to be added taxAdjValue.set("orderAdjustmentTypeId", "VAT_TAX"); // the amount will be different because we want to figure out how much of the price was // tax, and not how much tax needs to be added // the formula is: taxAmount = priceWithTax - (priceWithTax/(1+taxPercentage/100)) BigDecimal taxAmountIncluded = itemAmount.subtract( itemAmount.divide( BigDecimal.ONE.add( taxRate.divide(PERCENT_SCALE, 4, BigDecimal.ROUND_HALF_UP)), 3, BigDecimal.ROUND_HALF_UP)); taxAdjValue.set("amountAlreadyIncluded", taxAmountIncluded); taxAdjValue.set("amount", BigDecimal.ZERO); } else { taxAdjValue.set("orderAdjustmentTypeId", "SALES_TAX"); taxAdjValue.set("amount", taxAmount); } taxAdjValue.set("sourcePercentage", taxRate); taxAdjValue.set( "taxAuthorityRateSeqId", taxAuthorityRateProduct.getString("taxAuthorityRateSeqId")); // the primary Geo should be the main jurisdiction that the tax is for, and the secondary // would just be to define a parent or wrapping jurisdiction of the primary taxAdjValue.set("primaryGeoId", taxAuthGeoId); taxAdjValue.set("comments", taxAuthorityRateProduct.getString("description")); if (taxAuthPartyId != null) taxAdjValue.set("taxAuthPartyId", taxAuthPartyId); if (taxAuthGlAccountId != null) taxAdjValue.set("overrideGlAccountId", taxAuthGlAccountId); if (taxAuthGeoId != null) taxAdjValue.set("taxAuthGeoId", taxAuthGeoId); // check to see if this party has a tax ID for this, and if the party is tax exempt in the // primary (most-local) jurisdiction if (UtilValidate.isNotEmpty(billToPartyId) && UtilValidate.isNotEmpty(taxAuthGeoId)) { // see if partyId is a member of any groups, if so honor their tax exemptions // look for PartyRelationship with partyRelationshipTypeId=GROUP_ROLLUP, the partyIdTo is // the group member, so the partyIdFrom is the groupPartyId Set<String> billToPartyIdSet = FastSet.newInstance(); billToPartyIdSet.add(billToPartyId); List<GenericValue> partyRelationshipList = EntityUtil.filterByDate( delegator.findByAndCache( "PartyRelationship", UtilMisc.toMap( "partyIdTo", billToPartyId, "partyRelationshipTypeId", "GROUP_ROLLUP")), true); for (GenericValue partyRelationship : partyRelationshipList) { billToPartyIdSet.add(partyRelationship.getString("partyIdFrom")); } handlePartyTaxExempt( taxAdjValue, billToPartyIdSet, taxAuthGeoId, taxAuthPartyId, taxAmount, nowTimestamp, delegator); } else { Debug.logInfo( "NOTE: A tax calculation was done without a billToPartyId or taxAuthGeoId, so no tax exemptions or tax IDs considered; billToPartyId=[" + billToPartyId + "] taxAuthGeoId=[" + taxAuthGeoId + "]", module); } adjustments.add(taxAdjValue); if (productPrice != null && itemQuantity != null && productPrice.getBigDecimal("priceWithTax") != null && !"Y".equals(productPrice.getString("taxInPrice"))) { BigDecimal priceWithTax = productPrice.getBigDecimal("priceWithTax"); BigDecimal price = productPrice.getBigDecimal("price"); BigDecimal baseSubtotal = price.multiply(itemQuantity); BigDecimal baseTaxAmount = (baseSubtotal.multiply(taxRate)) .divide(PERCENT_SCALE, salestaxCalcDecimals, salestaxRounding); // Debug.logInfo("=================== priceWithTax=" + priceWithTax, module); // Debug.logInfo("=================== enteredTotalPriceWithTax=" + // enteredTotalPriceWithTax, module); // Debug.logInfo("=================== calcedTotalPriceWithTax=" + calcedTotalPriceWithTax, // module); // tax is not already in price so we want to add it in, but this is a VAT situation so // adjust to make it as accurate as possible // for VAT taxes if the calculated total item price plus calculated taxes is different // from what would be // expected based on the original entered price with taxes (if the price was entered this // way), then create // an adjustment that corrects for the difference, and this correction will be effectively // subtracted from the // price and not from the tax (the tax is meant to be calculated based on Tax Authority // rules and so should // not be shorted) // TODO (don't think this is needed, but just to keep it in mind): get this to work with // multiple VAT tax authorities instead of just one (right now will get incorrect totals // if there are multiple taxes included in the price) // TODO add constraint to ProductPrice lookup by any productStoreGroupId associated with // the current productStore BigDecimal enteredTotalPriceWithTax = priceWithTax.multiply(itemQuantity); BigDecimal calcedTotalPriceWithTax = (baseSubtotal).add(baseTaxAmount); if (!enteredTotalPriceWithTax.equals(calcedTotalPriceWithTax)) { // if the calced amount is higher than the entered amount we want the value to be // negative // to get it down to match the entered amount // so, subtract the calced amount from the entered amount (ie: correction = entered - // calced) BigDecimal correctionAmount = enteredTotalPriceWithTax.subtract(calcedTotalPriceWithTax); // Debug.logInfo("=================== correctionAmount=" + correctionAmount, module); GenericValue correctionAdjValue = delegator.makeValue("OrderAdjustment"); correctionAdjValue.set( "taxAuthorityRateSeqId", taxAuthorityRateProduct.getString("taxAuthorityRateSeqId")); correctionAdjValue.set("amount", correctionAmount); // don't set this, causes a doubling of the tax rate because calling code adds up all // tax rates: correctionAdjValue.set("sourcePercentage", taxRate); correctionAdjValue.set("orderAdjustmentTypeId", "VAT_PRICE_CORRECT"); // the primary Geo should be the main jurisdiction that the tax is for, and the // secondary would just be to define a parent or wrapping jurisdiction of the primary correctionAdjValue.set("primaryGeoId", taxAuthGeoId); correctionAdjValue.set("comments", taxAuthorityRateProduct.getString("description")); if (taxAuthPartyId != null) correctionAdjValue.set("taxAuthPartyId", taxAuthPartyId); if (taxAuthGlAccountId != null) correctionAdjValue.set("overrideGlAccountId", taxAuthGlAccountId); if (taxAuthGeoId != null) correctionAdjValue.set("taxAuthGeoId", taxAuthGeoId); adjustments.add(correctionAdjValue); } } } } catch (GenericEntityException e) { Debug.logError(e, "Problems looking up tax rates", module); return FastList.newInstance(); } return adjustments; }