📄 taxauthorityservices.java
字号:
// Loop through the products; get the taxCategory; and lookup each in the cache. for (int i = 0; i < itemProductList.size(); i++) { GenericValue product = (GenericValue) itemProductList.get(i); BigDecimal itemAmount = (BigDecimal) itemAmountList.get(i); BigDecimal itemPrice = (BigDecimal) itemPriceList.get(i); BigDecimal shippingAmount = (BigDecimal) itemShippingList.get(i); List taxList = null; if (shippingAddress != null) { taxList = getTaxAdjustments(delegator, product, productStore, billToPartyId, taxAuthoritySet, itemPrice, itemAmount, shippingAmount); } // this is an add and not an addAll because we want a List of Lists of GenericValues, one List of Adjustments per item itemAdjustments.add(taxList); } if (orderShippingAmount.doubleValue() > 0) { List taxList = getTaxAdjustments(delegator, null, productStore, billToPartyId, taxAuthoritySet, ZERO_BASE, ZERO_BASE, orderShippingAmount); orderAdjustments.addAll(taxList); } Map result = ServiceUtil.returnSuccess(); result.put("orderAdjustments", orderAdjustments); result.put("itemAdjustments", itemAdjustments); return result; } private static List getTaxAdjustments(GenericDelegator delegator, GenericValue product, GenericValue productStore, String billToPartyId, Set taxAuthoritySet, BigDecimal itemPrice, BigDecimal itemAmount, BigDecimal shippingAmount) { Timestamp nowTimestamp = UtilDateTime.nowTimestamp(); List adjustments = FastList.newInstance(); String payToPartyId = productStore.getString("payToPartyId"); // store expr EntityCondition storeCond = new EntityExpr("productStoreId", EntityOperator.EQUALS, productStore.get("productStoreId")); // build the TaxAuthority expressions (taxAuthGeoId, taxAuthPartyId) List taxAuthCondOrList = FastList.newInstance(); // start with the _NA_ TaxAuthority... taxAuthCondOrList.add(new EntityExpr( new EntityExpr("taxAuthPartyId", EntityOperator.EQUALS, "_NA_"), EntityOperator.AND, new EntityExpr("taxAuthGeoId", EntityOperator.EQUALS, "_NA_"))); Iterator taxAuthorityIter = taxAuthoritySet.iterator(); while (taxAuthorityIter.hasNext()) { GenericValue taxAuthority = (GenericValue) taxAuthorityIter.next(); EntityCondition taxAuthCond = new EntityExpr( new EntityExpr("taxAuthPartyId", EntityOperator.EQUALS, taxAuthority.getString("taxAuthPartyId")), EntityOperator.AND, new EntityExpr("taxAuthGeoId", EntityOperator.EQUALS, taxAuthority.getString("taxAuthGeoId"))); taxAuthCondOrList.add(taxAuthCond); } EntityCondition taxAuthoritiesCond = new EntityConditionList(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 // question: get all categories, or just a special type? for now let's do all categories... Set productCategoryIdSet = FastSet.newInstance(); List pcmList = delegator.findByAndCache("ProductCategoryMember", UtilMisc.toMap("productId", product.get("productId"))); pcmList = EntityUtil.filterByDate(pcmList, true); Iterator pcmIter = pcmList.iterator(); while (pcmIter.hasNext()) { GenericValue pcm = (GenericValue) pcmIter.next(); productCategoryIdSet.add(pcm.get("productCategoryId")); } if (productCategoryIdSet.size() == 0) { productCategoryCond = new EntityExpr("productCategoryId", EntityOperator.EQUALS, null); } else { productCategoryCond = new EntityExpr( new EntityExpr("productCategoryId", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr("productCategoryId", EntityOperator.IN, productCategoryIdSet)); } } else { productCategoryCond = new EntityExpr("productCategoryId", EntityOperator.EQUALS, null); } // build the main condition clause List mainExprs = UtilMisc.toList(storeCond, taxAuthoritiesCond, productCategoryCond); mainExprs.add(new EntityExpr(new EntityExpr("minItemPrice", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr("minItemPrice", EntityOperator.LESS_THAN_EQUAL_TO, itemPrice))); mainExprs.add(new EntityExpr(new EntityExpr("minPurchase", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr("minPurchase", EntityOperator.LESS_THAN_EQUAL_TO, itemAmount))); EntityCondition mainCondition = new EntityConditionList(mainExprs, EntityOperator.AND); // create the orderby clause List orderList = UtilMisc.toList("minItemPrice", "minPurchase", "fromDate"); // finally ready... do the rate query List lookupList = delegator.findByCondition("TaxAuthorityRateProduct", mainCondition, null, orderList); List 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 Iterator flIt = filteredList.iterator(); while (flIt.hasNext()) { GenericValue taxAuthorityRateProduct = (GenericValue) flIt.next(); 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 (taxAuthorityRateProduct != null && (taxAuthorityRateProduct.get("taxShipping") == null || (taxAuthorityRateProduct.get("taxShipping") != null && taxAuthorityRateProduct.getBoolean("taxShipping").booleanValue()))) { taxable = taxable.add(shippingAmount); } if (taxable.doubleValue() == 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, 3, BigDecimal.ROUND_CEILING); String taxAuthGeoId = taxAuthorityRateProduct.getString("taxAuthGeoId"); String taxAuthPartyId = taxAuthorityRateProduct.getString("taxAuthPartyId"); // get glAccountId from TaxAuthorityGlAccount entity using the ProductStore.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 adjValue = delegator.makeValue("OrderAdjustment", null); adjValue.set("taxAuthorityRateSeqId", taxAuthorityRateProduct.getString("taxAuthorityRateSeqId")); adjValue.set("amount", taxAmount); adjValue.set("sourcePercentage", taxRate); adjValue.set("orderAdjustmentTypeId", "SALES_TAX"); // 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 adjValue.set("primaryGeoId", taxAuthGeoId); adjValue.set("comments", taxAuthorityRateProduct.getString("description")); if (taxAuthPartyId != null) adjValue.set("taxAuthPartyId", taxAuthPartyId); if (taxAuthGlAccountId != null) adjValue.set("overrideGlAccountId", taxAuthGlAccountId); if (taxAuthGeoId != null) adjValue.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) && taxAuthGeoId != null) { // 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 billToPartyIdSet = FastSet.newInstance(); billToPartyIdSet.add(billToPartyId); List partyRelationshipList = EntityUtil.filterByDate(delegator.findByAndCache("PartyRelationship", UtilMisc.toMap("partyIdTo", billToPartyId, "partyRelationshipTypeId", "GROUP_ROLLUP")), true); Iterator partyRelationshipIter = partyRelationshipList.iterator(); while (partyRelationshipIter.hasNext()) { GenericValue partyRelationship = (GenericValue) partyRelationshipIter.next(); billToPartyIdSet.add(partyRelationship.get("partyIdFrom")); } List ptiConditionList = UtilMisc.toList( new EntityExpr("partyId", EntityOperator.IN, billToPartyIdSet), new EntityExpr("taxAuthGeoId", EntityOperator.EQUALS, taxAuthGeoId), new EntityExpr("taxAuthPartyId", EntityOperator.EQUALS, taxAuthPartyId)); ptiConditionList.add(new EntityExpr("fromDate", EntityOperator.LESS_THAN_EQUAL_TO, nowTimestamp)); ptiConditionList.add(new EntityExpr(new EntityExpr("thruDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr("thruDate", EntityOperator.GREATER_THAN, nowTimestamp))); EntityCondition ptiCondition = new EntityConditionList(ptiConditionList, EntityOperator.AND); // sort by -fromDate to get the newest (largest) first, just in case there is more than one, we only want the most recent valid one, should only be one per jurisdiction... List partyTaxInfos = delegator.findByCondition("PartyTaxAuthInfo", ptiCondition, null, UtilMisc.toList("-fromDate")); if (partyTaxInfos.size() > 0) { GenericValue partyTaxInfo = (GenericValue) partyTaxInfos.get(0); adjValue.set("customerReferenceId", partyTaxInfo.get("partyTaxId")); if ("Y".equals(partyTaxInfo.getString("isExempt"))) { adjValue.set("amount", new Double(0)); adjValue.set("exemptAmount", taxAmount); } } } 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(adjValue); } } catch (GenericEntityException e) { Debug.logError(e, "Problems looking up tax rates", module); return new ArrayList(); } return adjustments; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -