Class DefaultDelegatingTaxService<P extends BillingEventItem,Q extends BillingTaxDetail,R extends BillingProcessingRequestWithBillingEventDTO>
java.lang.Object
com.broadleafcommerce.billing.job.service.impl.DefaultDelegatingTaxService<P,Q,R>
- All Implemented Interfaces:
TaxService<P,Q, R>
public class DefaultDelegatingTaxService<P extends BillingEventItem,Q extends BillingTaxDetail,R extends BillingProcessingRequestWithBillingEventDTO>
extends Object
implements TaxService<P,Q,R>
This implementation of
TaxService calls TaxDelegate, which has a discovery
process to determine the best TaxProvider implementation based on configured properties,
the provided TaxCalculationRequest, and the ContextInfo.- Author:
- Kelly Tisdell (ktisdell), Chris Kittrell (ckittrell)
-
Field Summary
Fields -
Constructor Summary
ConstructorsConstructorDescriptionDefaultDelegatingTaxService(@NonNull com.broadleafcommerce.tax.delegate.TaxDelegate<?, ?> taxDelegate, @NonNull com.broadleafcommerce.common.extension.TypeFactory typeFactory) -
Method Summary
Modifier and TypeMethodDescriptionapplyTaxDetails(BillingEvent billingEvent, Map<P, List<Q>> itemsWithTaxDetails, com.broadleafcommerce.tax.domain.TaxResponseGroup taxResponseGroup, javax.money.MonetaryAmount totalGroupTax, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) applyTaxResponses(@NonNull com.broadleafcommerce.tax.domain.TaxCalculationResponse response, BillingEvent billingEvent, Map<P, List<Q>> itemsWithTaxDetails, javax.money.CurrencyUnit expectedCurrency, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) protected booleanbillingEventAddressHasSufficientData(BillingEventAddress billingEventAddress, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) buildEmptyTaxMap(List<P> billingEventItems) buildItemTaxes(@NonNull com.broadleafcommerce.tax.domain.TaxInfo taxInfo, P billingEventItem, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) AddBillingTaxDetailsto the billing event item.protected com.broadleafcommerce.tax.domain.TaxAddressbuildTaxAddress(BillingEventAddress billingEventAddress) protected com.broadleafcommerce.tax.domain.TaxCalculationGroupbuildTaxCalculationGroup(BillingEvent billingEvent, BillingEventAddress billingEventAddress, @NonNull List<com.broadleafcommerce.tax.domain.TaxItem> taxItems, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Builds aTaxCalculationGroup, which is used to calculate taxes for a group of items being shipped to or fulfilled at a particular Address.protected List<com.broadleafcommerce.tax.domain.TaxCalculationGroup>buildTaxCalculationGroups(BillingEvent billingEvent, BillingEventAddress billingEventAddress, List<com.broadleafcommerce.tax.domain.TaxItem> taxItems, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Builds a list ofgroups, which is used to calculate taxes for a group of items being shipped to or fulfilled at a particular Address.protected QbuildTaxDetailWithNonNumericalFields(com.broadleafcommerce.tax.domain.TaxDetail taxDetail, P billingEventItem) protected com.broadleafcommerce.tax.domain.TaxItembuildTaxItemForBillingEventItem(BillingEvent billingEvent, P billingEventItem, List<BillingEventItemAdjustment> itemAdjustments, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) protected javax.money.MonetaryAmountcalculatePreTaxItemTotal(P billingEventItem, List<BillingEventItemAdjustment> itemAdjustments, javax.money.CurrencyUnit currency) This adds up the item total for a given item prior to taxes.calculateTaxForBillingEventItems(R billingProcessingRequestWithBillingEventDTO, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) protected booleancanCalculateTaxes(BillingEvent billingEvent, @NonNull List<P> billingEventItems, BillingEventAddress billingEventAddress, javax.money.CurrencyUnit expectedCurrency, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) protected com.broadleafcommerce.tax.domain.TaxCalculationRequestcreateRequest(BillingEvent billingEvent, List<P> billingEventItems, Map<P, List<BillingEventItemAdjustment>> billingEventItemsWithAdjustments, BillingEventAddress billingEventAddress, javax.money.CurrencyUnit expectedCurrency, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) protected voiddebugLogTrimmedTaxResponse(@NotNull com.broadleafcommerce.tax.domain.TaxCalculationResponse response) protected StringdetermineBillingEventId(BillingEvent billingEvent, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) We require theBillingEvent.getId(), in most cases.protected StringdeterminePreferredProviderId(BillingEvent billingEvent, List<P> billingEventItems, BillingEventAddress billingEventAddress, boolean estimate, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) This method returns the "preferred"Tax Provider ID, which is determined byTaxProvider.getProviderId().protected com.broadleafcommerce.tax.domain.TaxCalculationResponseexecuteTaxCalculation(@NonNull com.broadleafcommerce.tax.domain.TaxCalculationRequest request, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) protected com.fasterxml.jackson.databind.ObjectMapperprotected com.broadleafcommerce.tax.delegate.TaxDelegate<?,?> protected StringgetTaxItemIdForBillingEventItem(BillingEvent billingEvent, P billingEventItem) Extension point to modify theTaxItem.getItemId()for tax items.protected com.broadleafcommerce.common.extension.TypeFactorygroupBillingEventItemsByNexus(@NonNull List<P> billingEventItems) protected booleanhasTaxItems(com.broadleafcommerce.tax.domain.TaxCalculationRequest request, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Determine if there are tax items on the given request.protected booleanisPreTaxBillingEventTotalGreaterThanZeroOrNull(BillingEvent billingEvent, javax.money.CurrencyUnit expectedCurrency, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) protected booleanitemIncludesTaxes(BillingEvent billingEvent, P billingEventItem, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) In some situations, especially in European countries, for example, merchants are required to display all prices including tax.protected booleanmapDoesNotContainTaxDetails(Map<P, List<Q>> itemsWithTaxDetailsMap) Determines whether the tax calculation was successful.protected voidsetAllTaxToZero(BillingEvent billingEvent, List<P> billingEventItems, javax.money.CurrencyUnit expectedCurrency, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Sets allitem tax totalsto 0 with the given currency.voidsetMapper(com.fasterxml.jackson.databind.ObjectMapper mapper) protected booleanshouldCalculateItemTaxes(BillingEvent billingEvent, P billingEventItem, List<BillingEventItemAdjustment> itemAdjustments, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
-
Field Details
-
TAX_CODE
- See Also:
-
-
Constructor Details
-
DefaultDelegatingTaxService
public DefaultDelegatingTaxService(@NonNull @NonNull com.broadleafcommerce.tax.delegate.TaxDelegate<?, ?> taxDelegate, @NonNull @NonNull com.broadleafcommerce.common.extension.TypeFactory typeFactory)
-
-
Method Details
-
calculateTaxForBillingEventItems
public Map<P,List<Q>> calculateTaxForBillingEventItems(R billingProcessingRequestWithBillingEventDTO, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) - Specified by:
calculateTaxForBillingEventItemsin interfaceTaxService<P extends BillingEventItem,Q extends BillingTaxDetail, R extends BillingProcessingRequestWithBillingEventDTO>
-
setAllTaxToZero
protected void setAllTaxToZero(BillingEvent billingEvent, List<P> billingEventItems, javax.money.CurrencyUnit expectedCurrency, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Sets allitem tax totalsto 0 with the given currency. It also sets thebilling event tax totalto 0 of the given currency. -
mapDoesNotContainTaxDetails
Determines whether the tax calculation was successful. If the given map is empty or does not contain anytax details, it must not have been.- Parameters:
itemsWithTaxDetailsMap- map of items with their tax details after tax calculation- Returns:
- whether this map contains tax details, and by extension, had its taxes calculated successfully
-
buildEmptyTaxMap
-
canCalculateTaxes
protected boolean canCalculateTaxes(@Nullable BillingEvent billingEvent, @NonNull @NonNull List<P> billingEventItems, @Nullable BillingEventAddress billingEventAddress, javax.money.CurrencyUnit expectedCurrency, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) -
isPreTaxBillingEventTotalGreaterThanZeroOrNull
protected boolean isPreTaxBillingEventTotalGreaterThanZeroOrNull(BillingEvent billingEvent, javax.money.CurrencyUnit expectedCurrency, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) -
billingEventAddressHasSufficientData
protected boolean billingEventAddressHasSufficientData(@Nullable BillingEventAddress billingEventAddress, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) -
hasTaxItems
protected boolean hasTaxItems(com.broadleafcommerce.tax.domain.TaxCalculationRequest request, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Determine if there are tax items on the given request.- Parameters:
request- TheTaxCalculationRequestto check.contextInfo- The context of this request.- Returns:
- FALSE if there are no
Tax Itemson the request. TRUE if there are any present.
-
groupBillingEventItemsByNexus
-
createRequest
protected com.broadleafcommerce.tax.domain.TaxCalculationRequest createRequest(BillingEvent billingEvent, List<P> billingEventItems, Map<P, List<BillingEventItemAdjustment>> billingEventItemsWithAdjustments, BillingEventAddress billingEventAddress, javax.money.CurrencyUnit expectedCurrency, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) -
determineBillingEventId
protected String determineBillingEventId(BillingEvent billingEvent, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) We require theBillingEvent.getId(), in most cases. However, if, for some reason, there is no ID available on the event, then we provide a UUID. The BillingEvent ID is generally used to tie requests together in someTax Provider systems. -
determinePreferredProviderId
@Nullable protected String determinePreferredProviderId(BillingEvent billingEvent, List<P> billingEventItems, BillingEventAddress billingEventAddress, boolean estimate, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) This method returns the "preferred"Tax Provider ID, which is determined byTaxProvider.getProviderId(). By default, this will be null. This provides a hook point to allow someone to specify the Tax Provider that should be prioritized for use. For example, you may wish to returnSimpleTaxProvider.SIMPLE_TAX_PROVIDER_IDfor estimates. In this case you could override this method to do so if theestimateargument is true, and return null otherwise. To be clear, this does not guarantee that theTaxProviderspecified will be used; only that it will be prioritized for use. If there is no TaxProvider registered with that ID, then it will be ignored. Or, if the TaxProvider exists with that ID, but it cannot handle the request, then it will be ignored. -
shouldCalculateItemTaxes
protected boolean shouldCalculateItemTaxes(BillingEvent billingEvent, P billingEventItem, List<BillingEventItemAdjustment> itemAdjustments, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) -
calculatePreTaxItemTotal
protected javax.money.MonetaryAmount calculatePreTaxItemTotal(P billingEventItem, List<BillingEventItemAdjustment> itemAdjustments, javax.money.CurrencyUnit currency) This adds up the item total for a given item prior to taxes. It adjusts the unit price with the total sum of all active adjustments for this item. Then, that adjusted price is multiplied by item quantity and returned.Note that
event-level adjustmentsare prorated into each item'sBillingEventItemAdjustmentwhen the billing event is created inDefaultBillingEventService.generateProratedEventItemAdjustments(List, List). -
buildTaxItemForBillingEventItem
protected com.broadleafcommerce.tax.domain.TaxItem buildTaxItemForBillingEventItem(BillingEvent billingEvent, P billingEventItem, List<BillingEventItemAdjustment> itemAdjustments, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) -
itemIncludesTaxes
protected boolean itemIncludesTaxes(BillingEvent billingEvent, P billingEventItem, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) In some situations, especially in European countries, for example, merchants are required to display all prices including tax. This is especially common with VAT. So, in some situations the price of an item will include Value Added Taxes. Some providers (e.g. Avalara) will attempt to back-calculate the taxes from the price of the item if we indicate that tax is included in the price. While the customer does not need to pay additional taxes, this allows us to calculate taxes owed for this item, which we can store on the tax details for informational purposes and remediation. NOTE: By default, this method returns false. Broadleaf Commerce does not currently provide a mechanism to determine if tax is included because catalogs, products, variants, and even pricing can be shared across applications and countries. Implementors may wish to override this method to return true under certain circumstances. For example, if the destination country is a European country (e.g. GB or FR) and/or the currency is a European currency, then you may wish to return true. TheContextInfo(i.e. the tenant or application) may also inform this decision. -
buildTaxCalculationGroups
protected List<com.broadleafcommerce.tax.domain.TaxCalculationGroup> buildTaxCalculationGroups(BillingEvent billingEvent, BillingEventAddress billingEventAddress, List<com.broadleafcommerce.tax.domain.TaxItem> taxItems, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Builds a list ofgroups, which is used to calculate taxes for a group of items being shipped to or fulfilled at a particular Address.Some tax providers desire requests to be sent in particular groups, such as ones from the same country or for a single business entity. This method serves as a hook-point to be extended to create such a customization.
-
buildTaxCalculationGroup
protected com.broadleafcommerce.tax.domain.TaxCalculationGroup buildTaxCalculationGroup(BillingEvent billingEvent, BillingEventAddress billingEventAddress, @NonNull @NonNull List<com.broadleafcommerce.tax.domain.TaxItem> taxItems, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Builds aTaxCalculationGroup, which is used to calculate taxes for a group of items being shipped to or fulfilled at a particular Address. -
buildTaxAddress
protected com.broadleafcommerce.tax.domain.TaxAddress buildTaxAddress(BillingEventAddress billingEventAddress) -
executeTaxCalculation
protected com.broadleafcommerce.tax.domain.TaxCalculationResponse executeTaxCalculation(@NonNull @NonNull com.broadleafcommerce.tax.domain.TaxCalculationRequest request, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) -
applyTaxResponses
protected Map<P,List<Q>> applyTaxResponses(@NonNull @NonNull com.broadleafcommerce.tax.domain.TaxCalculationResponse response, BillingEvent billingEvent, Map<P, List<Q>> itemsWithTaxDetails, javax.money.CurrencyUnit expectedCurrency, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) -
applyTaxDetails
-
debugLogTrimmedTaxResponse
protected void debugLogTrimmedTaxResponse(@NotNull @NotNull com.broadleafcommerce.tax.domain.TaxCalculationResponse response) -
getTaxItemIdForBillingEventItem
Extension point to modify theTaxItem.getItemId()for tax items. For someTaxProviders, there may be an affix likeFR(for freight) to add to theBillingEventItem.getId(). Alternatively, some providers may combine the item id with the billing event id.- Parameters:
billingEvent- billing event from which to derive an idbillingEventItem- item from which to derive an id- Returns:
TaxItem.getItemId()for billing event item tax items
-
buildItemTaxes
protected List<Q> buildItemTaxes(@NonNull @NonNull com.broadleafcommerce.tax.domain.TaxInfo taxInfo, @NonNull P billingEventItem, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) AddBillingTaxDetailsto the billing event item.- Parameters:
taxInfo- The tax infobillingEventItem- The billing event itemcontextInfo- the contextInfo for this request
-
buildTaxDetailWithNonNumericalFields
-
getTypeFactory
protected com.broadleafcommerce.common.extension.TypeFactory getTypeFactory() -
getTaxDelegate
protected com.broadleafcommerce.tax.delegate.TaxDelegate<?,?> getTaxDelegate() -
getMapper
protected com.fasterxml.jackson.databind.ObjectMapper getMapper() -
setMapper
@Autowired public void setMapper(com.fasterxml.jackson.databind.ObjectMapper mapper)
-