/*
* Licensed to csti consulting
* You may obtain a copy of the License at
*
* http://www.csticonsulting.com
* Copyright (c) 2006-Aug 24, 2010 Consultation CS-TI inc.
*
* 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 com.salesmanager.core.service.tax;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.salesmanager.core.constants.Constants;
import com.salesmanager.core.constants.ShippingConstants;
import com.salesmanager.core.constants.TaxConstants;
import com.salesmanager.core.entity.catalog.Product;
import com.salesmanager.core.entity.customer.Customer;
import com.salesmanager.core.entity.merchant.MerchantConfiguration;
import com.salesmanager.core.entity.merchant.MerchantStore;
import com.salesmanager.core.entity.orders.OrderProduct;
import com.salesmanager.core.entity.orders.OrderProductPrice;
import com.salesmanager.core.entity.orders.OrderTotalSummary;
import com.salesmanager.core.entity.orders.OrderTotalLine;
import com.salesmanager.core.entity.reference.Country;
import com.salesmanager.core.entity.reference.GeoZone;
import com.salesmanager.core.entity.reference.ZoneToGeoZone;
import com.salesmanager.core.entity.tax.TaxClass;
import com.salesmanager.core.entity.tax.TaxRate;
import com.salesmanager.core.entity.tax.TaxRateDescription;
import com.salesmanager.core.entity.tax.TaxRateDescriptionId;
import com.salesmanager.core.entity.tax.TaxRateDescriptionTaxTemplate;
import com.salesmanager.core.entity.tax.TaxRateDescriptionTaxTemplateId;
import com.salesmanager.core.entity.tax.TaxRateTaxTemplate;
import com.salesmanager.core.module.model.application.TaxModule;
import com.salesmanager.core.service.ServiceFactory;
import com.salesmanager.core.service.cache.RefCache;
import com.salesmanager.core.service.catalog.impl.db.dao.IProductDao;
import com.salesmanager.core.service.merchant.ConfigurationRequest;
import com.salesmanager.core.service.merchant.ConfigurationResponse;
import com.salesmanager.core.service.merchant.MerchantService;
import com.salesmanager.core.service.reference.impl.dao.IGeoZoneDao;
import com.salesmanager.core.service.reference.impl.dao.IZoneToGeoZoneDao;
import com.salesmanager.core.service.shipping.ShippingService;
import com.salesmanager.core.service.tax.impl.dao.ITaxClassDao;
import com.salesmanager.core.service.tax.impl.dao.ITaxRateDao;
import com.salesmanager.core.service.tax.impl.dao.ITaxRateDescriptionDao;
import com.salesmanager.core.util.CurrencyUtil;
import com.salesmanager.core.util.LabelUtil;
import com.salesmanager.core.util.LanguageUtil;
import com.salesmanager.core.util.SpringUtil;
@Service
public class TaxService {
@Autowired
private ITaxClassDao taxClassDao;
@Autowired
private IGeoZoneDao geoZoneDao;
@Autowired
private IZoneToGeoZoneDao zoneToGeoZoneDao;
@Autowired
private ITaxRateDao taxRateDao;
@Autowired
private ITaxRateDescriptionDao taxRateDescriptionDao;
@Autowired
private IProductDao productDao;
@Transactional
public Collection<TaxRateTaxTemplate> findByGeoZoneCountryId(int countryId)
throws Exception {
return taxRateDao.findByZoneCountryId(countryId);
}
@Transactional
public Collection<TaxRateTaxTemplate> findBySchemeId(int schemeId)
throws Exception {
return taxRateDao.findBySchemeId(schemeId);
}
@Transactional
public Collection<TaxRate> findByCountryIdZoneIdAndClassId(int countryId,
int zoneId, long taxClassId, int merchantId) throws Exception {
return taxRateDao.findByCountryIdZoneIdAndClassId(countryId, zoneId,
taxClassId, merchantId);
}
/**
* Calculates tax on a BigDecimal price, returns the price with tax
*
* @param amount
* @param customer
* @param merchantId
* @return
* @throws Exception
*/
@Transactional
public BigDecimal calculateTax(BigDecimal amount, long taxClassId,
Customer customer, int merchantId) throws Exception {
// no tax calculation id taxClassId==-1
if (taxClassId == -1) {
return amount;
}
MerchantService mservice = (MerchantService) ServiceFactory
.getService(ServiceFactory.MerchantService);
ConfigurationRequest request = new ConfigurationRequest(merchantId,
ShippingConstants.MODULE_TAX_BASIS);
ConfigurationResponse response = mservice.getConfiguration(request);
String taxBasis = TaxConstants.SHIPPING_TAX_BASIS;
// get tax basis
MerchantConfiguration taxConf = response
.getMerchantConfiguration(TaxConstants.MODULE_TAX_BASIS);
if (taxConf != null
&& !StringUtils.isBlank(taxConf.getConfigurationValue())) {// tax
// basis
taxBasis = taxConf.getConfigurationValue();
}
Collection taxCollection = null;
if (taxBasis.equals(TaxConstants.SHIPPING_TAX_BASIS)) {
taxCollection = taxRateDao.findByCountryIdZoneIdAndClassId(customer
.getCustomerCountryId(), customer.getCustomerZoneId(),
taxClassId, merchantId);
} else {
taxCollection = taxRateDao.findByCountryIdZoneIdAndClassId(customer
.getCustomerBillingCountryId(), customer
.getCustomerBillingZoneId(), taxClassId, merchantId);
}
BigDecimal currentAmount = new BigDecimal(0);
currentAmount.setScale(2, BigDecimal.ROUND_HALF_UP);
if (taxCollection != null) {
Iterator i = taxCollection.iterator();
while (i.hasNext()) {
TaxRate trv = (TaxRate) i.next();
BigDecimal amountForCalculation = amount;
if (trv.isPiggyback()) {
amountForCalculation = amountForCalculation
.add(currentAmount);
}
double value = ((trv.getTaxRate().doubleValue() * amountForCalculation
.doubleValue()) / 100)
+ amountForCalculation.doubleValue();
currentAmount = currentAmount.add(new BigDecimal(value));
}
}
return currentAmount;
}
/**
* Returns a Collection of TaxRate for a given zone information
*
* @param taxClassId
* @param customerCountryId
* @param customerZoneId
* @param merchantId
* @return
* @throws Exception
*/
@Transactional
public Collection<TaxRate> getTax(long taxClassId, int customerCountryId,
int customerZoneId, int merchantId) throws Exception {
return taxRateDao.findByCountryIdZoneIdAndClassId(customerCountryId,
customerZoneId, taxClassId, merchantId);
}
/**
* Calculates tax on an OrderTotalSummary object (products applicable,
* shipping...), creates and set the shopping cart lines. Returns the amount
* with tax
*
* @param summary
* @param amount
* @param customer
* @param merchantId
* @return
* @throws Exception
*/
@Transactional
public OrderTotalSummary calculateTax(OrderTotalSummary summary,
Collection<OrderProduct> products, Customer customer,
int merchantId, Locale locale, String currency) throws Exception {
MerchantService mservice = (MerchantService) ServiceFactory
.getService(ServiceFactory.MerchantService);
MerchantStore store = mservice.getMerchantStore(merchantId);
Map productsTax = new HashMap();
//rounding definition
BigDecimal totalTaxAmount = new BigDecimal(0);
//totalTaxAmount.setScale(2, BigDecimal.ROUND_DOWN);
// check if tax is applicable and build a map
// of tax class - product
if (products != null) {
Iterator prodIt = products.iterator();
while (prodIt.hasNext()) {
OrderProduct prod = (OrderProduct) prodIt.next();
if (prod.getTaxClassId() > -1) {
BigDecimal groupBeforeTaxAmount = (BigDecimal) productsTax
.get(prod.getTaxClassId());
if (groupBeforeTaxAmount == null) {
groupBeforeTaxAmount = new BigDecimal("0");
}
BigDecimal finalPrice = prod.getFinalPrice();// unit price +
// attribute
// * qty
// finalPrice = finalPrice.multiply(new
// BigDecimal(prod.getProductQuantity()));
groupBeforeTaxAmount = groupBeforeTaxAmount.add(finalPrice);
// getPrices
Set prices = prod.getPrices();
// List prices = prod.getRelatedPrices();
if (prices != null) {
Iterator ppriceIter = prices.iterator();
while (ppriceIter.hasNext()) {
OrderProductPrice pprice = (OrderProductPrice) ppriceIter
.next();
if (!pprice.isDefaultPrice()) {// related price
// activation...
// PriceModule module =
// (PriceModule)SpringUtil.getBean(pprice.getProductPriceModuleName());
// if(module.isTaxApplicable()) {//related price
// becomes taxeable
// if(pprice.isProductHasTax()) {
// groupBeforeTaxAmount =
// groupBeforeTaxAmount.add(ProductUtil.determinePrice(pprice));
BigDecimal ppPrice = pprice
.getProductPriceAmount();
ppPrice = ppPrice.multiply(new BigDecimal(prod
.getProductQuantity()));
groupBeforeTaxAmount = groupBeforeTaxAmount
.add(ppPrice);
// }
}
}
}
BigDecimal credits = prod
.getApplicableCreditOneTimeCharge();
groupBeforeTaxAmount = groupBeforeTaxAmount
.subtract(credits);
productsTax.put(prod.getTaxClassId(), groupBeforeTaxAmount);
}
}
}
if (productsTax.size() == 0) {
return summary;
}
// determine if tax applies on billing or shipping address
// get shipping & tax informations
ConfigurationRequest request = new ConfigurationRequest(merchantId);
ConfigurationResponse response = mservice.getConfiguration(request);
String taxBasis = TaxConstants.SHIPPING_TAX_BASIS;
// get tax basis
MerchantConfiguration taxConf = response
.getMerchantConfiguration(TaxConstants.MODULE_TAX_BASIS);
if (taxConf != null
&& !StringUtils.isBlank(taxConf.getConfigurationValue())) {// tax
// basis
taxBasis = taxConf.getConfigurationValue();
}
// tax on shipping
if (summary.getShippingTotal() != null
&& summary.getShippingTotal().floatValue() > 0) {
MerchantConfiguration shippingTaxConf = response
.getMerchantConfiguration(ShippingConstants.MODULE_SHIPPING_TAX_CLASS);
if (shippingTaxConf != null
&& !StringUtils.isBlank(shippingTaxConf
.getConfigurationValue())) {// tax on shipping
long taxClass = Long.parseLong(shippingTaxConf
.getConfigurationValue());
BigDecimal groupSubTotal = (BigDecimal) productsTax
.get(taxClass);
if (groupSubTotal == null) {
groupSubTotal = new BigDecimal("0");
productsTax.put(taxClass, groupSubTotal);
}
groupSubTotal = groupSubTotal.add(summary.getShippingTotal());
productsTax.put(taxClass, groupSubTotal);
}
}
Map taxDescriptionsHolder = new TreeMap();
Iterator taxMapIter = productsTax.keySet().iterator();
while (taxMapIter.hasNext()) {// get each tax class
long key = (Long) taxMapIter.next();
// List taxClassGroup = (List)productsTax.get(key);
int countryId = 0;
Collection taxCollection = null;
if (taxBasis.equals(TaxConstants.SHIPPING_TAX_BASIS)) {
if (store.getCountry() != customer.getCustomerCountryId()) {
return summary;
}
taxCollection = taxRateDao.findByCountryIdZoneIdAndClassId(
customer.getCustomerCountryId(), customer
.getCustomerZoneId(), key, merchantId);
countryId = customer.getCustomerCountryId();
} else { // BILLING
if (store.getCountry() != customer
.getCustomerBillingCountryId()) {
return summary;
}
taxCollection = taxRateDao.findByCountryIdZoneIdAndClassId(
customer.getCustomerBillingCountryId(), customer
.getCustomerBillingZoneId(), key, merchantId);
countryId = customer.getCustomerBillingCountryId();
}
if (taxCollection == null || taxCollection.size() == 0) {// no tax
continue;
}
Map countries = RefCache.getCountriesMap();
Country c = (Country) countries.get(countryId);
if (c != null) {// tax adjustment rules
TaxModule module = (TaxModule) SpringUtil.getBean(c
.getCountryIsoCode2());
if (module != null) {
taxCollection = module.adjustTaxRate(taxCollection, store);
}
}
//BigDecimal beforeTaxAmount = new BigDecimal("0");
//beforeTaxAmount.setScale(2, BigDecimal.ROUND_HALF_UP);
BigDecimal groupSubTotal = (BigDecimal) productsTax.get(key);
//beforeTaxAmount = beforeTaxAmount.add(groupSubTotal);
BigDecimal beforeTaxAmount = groupSubTotal;
beforeTaxAmount.setScale(2, BigDecimal.ROUND_HALF_UP);
// iterate through tax collection and calculate tax lines
if (taxCollection != null) {
Iterator i = taxCollection.iterator();
while (i.hasNext()) {
TaxRate trv = (TaxRate) i.next();
// double value = ((trv.getTaxRate().doubleValue() *
// beforeTaxAmount.doubleValue())/100)+beforeTaxAmount.doubleValue();
double trDouble = trv.getTaxRate().doubleValue();
// if piggy back, add tax to subtotal
BigDecimal amount = beforeTaxAmount;
if (trv.isPiggyback()) {
// add previous calculated tax on top of subtotal
amount = amount.add(totalTaxAmount);
}
// commented for piggyback
// double beforeTaxDouble = beforeTaxAmount.doubleValue();
double beforeTaxDouble = amount.doubleValue();
double value = ((trDouble * beforeTaxDouble) / 100);
BigDecimal nValue = BigDecimal.valueOf(value);
//BigDecimal nValue = new BigDecimal(value);
nValue.setScale(2, BigDecimal.ROUND_HALF_UP);
//nValue = nValue.add(new BigDecimal(value));
// commented for piggyback
// beforeTaxAmount = beforeTaxAmount.add(nValue);
//BigDecimal bdValue = nValue;
String am = CurrencyUtil.getAmount(nValue, store.getCurrency());
/** this one **/
totalTaxAmount = totalTaxAmount.add(new BigDecimal(am));
String name = LabelUtil.getInstance().getText(locale,
"label.generic.tax");
OrderTotalLine line = (OrderTotalLine) taxDescriptionsHolder
.get(trv.getZoneToGeoZone().getGeoZoneId());
if (line == null) {
// tax description
line = new OrderTotalLine();
Set descriptionsSet = trv.getDescriptions();
if (descriptionsSet != null) {
Iterator li = descriptionsSet.iterator();
while (li.hasNext()) {
TaxRateDescription description = (TaxRateDescription) li
.next();
if (description.getId().getLanguageId() == LanguageUtil
.getLanguageNumberCode(locale
.getLanguage())) {
name = description.getTaxDescription();
break;
}
}
}
line.setText(name);
line.setCost(nValue);
line.setCostFormated(CurrencyUtil
.displayFormatedAmountWithCurrency(nValue,
currency));
taxDescriptionsHolder.put(trv.getZoneToGeoZone()
.getGeoZoneId(), line);
} else {// needs to re-use the same shopping cart line
BigDecimal cost = line.getCost();
cost = cost.add(nValue);
line.setCostFormated(CurrencyUtil
.displayFormatedAmountWithCurrency(cost,
currency));
}
// now set tax on producs
Iterator prodIt = products.iterator();
while (prodIt.hasNext()) {
OrderProduct prod = (OrderProduct) prodIt.next();
if (prod.getTaxClassId() == key) {
// calculate tax for this product
BigDecimal price = prod.getProductPrice();
BigDecimal productTax = prod.getProductTax();
if (productTax == null) {
productTax = new BigDecimal("0");
}
price = price.add(productTax);
double pTax = ((trDouble * price.doubleValue()) / 100);
prod.setProductTax(new BigDecimal(pTax));
}
}
}// end while
}
Iterator titer = taxDescriptionsHolder.keySet().iterator();
while (titer.hasNext()) {
long lineKey = (Long) titer.next();
OrderTotalLine line = (OrderTotalLine) taxDescriptionsHolder
.get(lineKey);
summary.addTaxPrice(line);
}
}
summary.setTaxTotal(totalTaxAmount);
return summary;
}
/**
* Returns a Collection of tax class for a given merchant id. It will
* retreive also entries where merchantid = 0
*/
@Transactional
public List<TaxClass> getTaxClasses(int merchantid) throws Exception {
return taxClassDao.findByMerchantId(merchantid);
}
@Transactional
public TaxClass getTaxClass(long taxclassId) throws Exception {
return taxClassDao.findById(taxclassId);
}
/**
* Persist a new TaxClass or update an existing one
*
* @param taxClass
* @throws Exception
*/
@Transactional
public void saveOrUpdateTaxClass(TaxClass taxClass) throws Exception {
if (taxClass.getTaxClassId() == 0) {
taxClassDao.persist(taxClass);
} else {
taxClassDao.saveOrUpdate(taxClass);
}
}
@Transactional
public void deleteTaxClass(TaxClass taxClass) throws Exception {
// need to update all taxrates to basic tax class
List taxrates = taxRateDao.findByTaxClassId(taxClass.getTaxClassId());
if (taxrates != null) {
Iterator i = taxrates.iterator();
while (i.hasNext()) {
TaxRate tr = (TaxRate) i.next();
tr.setTaxClassId(TaxConstants.DEFAULT_TAX_CLASS_ID);
taxRateDao.saveOrUpdate(tr);
}
}
// products
Collection products = productDao.findByTaxClassId(taxClass
.getTaxClassId());
if (products != null) {
Iterator i = products.iterator();
while (i.hasNext()) {
Product p = (Product) i.next();
p.setProductTaxClassId(TaxConstants.DEFAULT_TAX_CLASS_ID);
productDao.saveOrUpdate(p);
}
}
// update shipping tax class
ShippingService service = (ShippingService) ServiceFactory
.getService(ServiceFactory.ShippingService);
service.setShippingTaxClass(TaxConstants.DEFAULT_TAX_CLASS_ID, taxClass
.getMerchantId());
taxClassDao.delete(taxClass);
}
@Transactional
public void deleteTaxConfiguration(int merchantid) throws Exception {
MerchantService mservice = (MerchantService) ServiceFactory
.getService(ServiceFactory.MerchantService);
mservice.cleanConfigurationLikeKey("MODULE_TAX_", merchantid);
Collection zones = geoZoneDao.findByMerchantId(merchantid);
if (zones != null) {
geoZoneDao.deleteAll(zones);
}
Collection geozones = zoneToGeoZoneDao.findByMerchantId(merchantid);
if (geozones != null) {
zoneToGeoZoneDao.deleteAll(geozones);
}
List taxRateIdList = null;
Collection taxrates = taxRateDao.findByMerchantId(merchantid);
if (taxrates != null) {
taxRateIdList = new ArrayList();
Iterator i = taxrates.iterator();
while (i.hasNext()) {
TaxRate tr = (TaxRate) i.next();
long id = tr.getTaxRateId();
Collection taxratesdesc = taxRateDescriptionDao
.findByTaxRateId(id);
taxRateDescriptionDao.deleteAll(taxratesdesc);
}
taxRateDao.deleteAll(taxrates);
}
Collection taxclass = taxClassDao.findByOwnerMerchantId(merchantid);
if (taxclass != null) {
taxClassDao.deleteAll(taxclass);
}
}
@Transactional
public void deleteTaxRate(TaxRate taxRate) throws Exception {
Set descriptions = taxRate.getDescriptions();
if (descriptions != null) {
taxRateDescriptionDao.deleteAll(descriptions);
}
taxRateDao.delete(taxRate);
}
/**
* Returns a TaxRate entity based on the taxrateid
*
* @param taxRateId
* @return
* @throws Exception
*/
@Transactional
public TaxRate getTaxRate(long taxRateId) throws Exception {
TaxRate rate = taxRateDao.findById(taxRateId);
if (rate != null) {
Set descriptions = taxRateDescriptionDao.findByTaxRateId(taxRateId);
rate.setDescriptions(descriptions);
}
return rate;
}
/**
* Load all taxes for a given merchantId as well as all collections
*
* @param merchantId
* @return
* @throws Exception
*/
@Transactional
public Collection<TaxRate> getTaxRates(int merchantId) throws Exception {
return taxRateDao.findByMerchantId(merchantId);
}
@Transactional
public void saveOrUpdateTaxRate(TaxRate taxRate, int countryId, int zoneId,
int merchantId) throws Exception {
if (taxRate.getTaxRateId() > 0) {// update
taxRateDao.saveOrUpdate(taxRate);
if (taxRate.getDescriptions() != null) {
taxRateDescriptionDao
.saveOrUpdateAll(taxRate.getDescriptions());
}
} else { // create
GeoZone geoZone = new GeoZone();
geoZone.setMerchantId(merchantId);
Map countries = RefCache.getAllcountriesmap(Constants.ENGLISH);
Country country = (Country) countries.get(countryId);
if (country == null) {
throw new Exception("Cannoy retreive a country for countryId "
+ countryId);
}
geoZone.setGeoZoneName(country.getCountryName() + "-TAX");
geoZoneDao.persist(geoZone);
ZoneToGeoZone ztGeoZone = new ZoneToGeoZone();
ztGeoZone.setMerchantId(merchantId);
ztGeoZone.setGeoZoneId(geoZone.getGeoZoneId());
ztGeoZone.setZoneId(zoneId);
ztGeoZone.setZoneCountryId(countryId);
zoneToGeoZoneDao.persist(ztGeoZone);
Integer priority = taxRate.getTaxPriority();
if (priority == null) {
priority = 0;
}
Collection existingRates = taxRateDao.findByCountryId(countryId,
merchantId);
if (existingRates != null && existingRates.size() > 0) {
Iterator erit = existingRates.iterator();
while (erit.hasNext()) {
TaxRate trv = (TaxRate) erit.next();
if (trv.getZoneToGeoZone() != null
&& trv.getZoneToGeoZone().getZoneId() == zoneId) {
Integer p = trv.getTaxPriority();
if (p != null && p > priority) {
priority = p + 1;
}
}
}
}
taxRate.setTaxPriority(priority);
taxRate.setTaxZoneId(geoZone.getGeoZoneId());
taxRate.setMerchantId(merchantId);
taxRateDao.persist(taxRate);
if (taxRate.getDescriptions() != null) {
Iterator it = taxRate.getDescriptions().iterator();
while (it.hasNext()) {
TaxRateDescription desc = (TaxRateDescription) it.next();
TaxRateDescriptionId id = desc.getId();
if (id == null || id.getLanguageId() == 0) {
throw new Exception(
"Need to configure a taxdescriptionid or the languageid for each description");
}
id.setTaxRateId(taxRate.getTaxRateId());
}
taxRateDescriptionDao
.saveOrUpdateAll(taxRate.getDescriptions());
}
}
}
@Transactional
public void createTaxRates(int schemeId, int merchantId, int countryId,
int zoneId) throws Exception {
/**
* if tax rate == 0 this means a new entry, so it will require a new -
* GEO_ZONE - ZONE_TO_GEO_ZONE - TAX_RATE - TAX_RATE_DESCRIPTION
**/
Collection txs = this.findBySchemeId(schemeId);
if (txs != null) {
Iterator i = txs.iterator();
while (i.hasNext()) {
TaxRateTaxTemplate t = (TaxRateTaxTemplate) i.next();
TaxRate taxRate = new TaxRate();
taxRate.setTaxClassId(t.getTaxClassId());
taxRate.setTaxPriority(t.getTaxPriority());
taxRate.setTaxZoneId(t.getZoneToGeoZone().getGeoZoneId());
taxRate.setTaxRate(t.getTaxRate());
taxRate.setMerchantId(merchantId);
taxRate.setPiggyback(t.isPiggyback());
Set descriptions = t.getDescriptions();
if (descriptions != null) {
HashSet descriptionset = new HashSet();
Iterator desci = descriptions.iterator();
while (desci.hasNext()) {
TaxRateDescriptionTaxTemplate trt = (TaxRateDescriptionTaxTemplate) desci
.next();
TaxRateDescriptionTaxTemplateId id = trt.getId();
TaxRateDescriptionId newId = new TaxRateDescriptionId();
newId.setLanguageId(id.getLanguageId());
newId.setTaxRateId(id.getTaxRateId());
TaxRateDescription newDesc = new TaxRateDescription();
newDesc.setTaxDescription(trt.getTaxDescription());
newDesc.setId(newId);
descriptionset.add(newDesc);
}
taxRate.setDescriptions(descriptionset);
}
this.saveOrUpdateTaxRate(taxRate, countryId, t
.getZoneToGeoZone().getZoneId(), merchantId);
}
}
}
}