
com.liferay.commerce.internal.price.CommerceProductPriceCalculationV2Impl Maven / Gradle / Ivy
/**
* SPDX-FileCopyrightText: (c) 2000 Liferay, Inc. https://liferay.com
* SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06
*/
package com.liferay.commerce.internal.price;
import com.liferay.commerce.context.CommerceContext;
import com.liferay.commerce.currency.model.CommerceCurrency;
import com.liferay.commerce.currency.model.CommerceMoney;
import com.liferay.commerce.currency.service.CommerceCurrencyLocalService;
import com.liferay.commerce.discount.CommerceDiscountCalculation;
import com.liferay.commerce.discount.CommerceDiscountValue;
import com.liferay.commerce.discount.application.strategy.CommerceDiscountApplicationStrategy;
import com.liferay.commerce.discount.application.strategy.CommerceDiscountApplicationStrategyRegistry;
import com.liferay.commerce.internal.util.CommercePriceConverterUtil;
import com.liferay.commerce.model.CommerceOrder;
import com.liferay.commerce.price.CommerceProductPrice;
import com.liferay.commerce.price.CommerceProductPriceCalculation;
import com.liferay.commerce.price.CommerceProductPriceImpl;
import com.liferay.commerce.price.CommerceProductPriceRequest;
import com.liferay.commerce.price.list.constants.CommercePriceListConstants;
import com.liferay.commerce.price.list.discovery.CommercePriceListDiscovery;
import com.liferay.commerce.price.list.model.CommercePriceEntry;
import com.liferay.commerce.price.list.model.CommercePriceList;
import com.liferay.commerce.price.list.model.CommerceTierPriceEntry;
import com.liferay.commerce.price.list.service.CommercePriceEntryLocalService;
import com.liferay.commerce.price.list.service.CommercePriceListLocalService;
import com.liferay.commerce.price.list.service.CommerceTierPriceEntryLocalService;
import com.liferay.commerce.pricing.configuration.CommercePricingConfiguration;
import com.liferay.commerce.pricing.constants.CommercePricingConstants;
import com.liferay.commerce.pricing.modifier.CommercePriceModifierHelper;
import com.liferay.commerce.product.constants.CommerceChannelAccountEntryRelConstants;
import com.liferay.commerce.product.model.CPInstance;
import com.liferay.commerce.product.model.CPInstanceUnitOfMeasure;
import com.liferay.commerce.product.model.CommerceCatalog;
import com.liferay.commerce.product.model.CommerceChannel;
import com.liferay.commerce.product.model.CommerceChannelAccountEntryRel;
import com.liferay.commerce.product.service.CPInstanceLocalService;
import com.liferay.commerce.product.service.CPInstanceUnitOfMeasureLocalService;
import com.liferay.commerce.util.CommerceUtil;
import com.liferay.osgi.service.tracker.collections.map.ServiceReferenceMapperFactory;
import com.liferay.osgi.service.tracker.collections.map.ServiceTrackerMap;
import com.liferay.osgi.service.tracker.collections.map.ServiceTrackerMapFactory;
import com.liferay.petra.string.StringPool;
import com.liferay.portal.configuration.module.configuration.ConfigurationProvider;
import com.liferay.portal.kernel.dao.orm.QueryUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.module.configuration.ConfigurationException;
import com.liferay.portal.kernel.util.BigDecimalUtil;
import com.liferay.portal.kernel.workflow.WorkflowConstants;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.List;
import org.osgi.framework.BundleContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
/**
* @author Riccardo Alberti
*/
@Component(service = CommerceProductPriceCalculation.class)
public class CommerceProductPriceCalculationV2Impl
extends BaseCommerceProductPriceCalculation {
@Override
public CommerceMoney getBasePrice(
long cpInstanceId, CommerceCurrency commerceCurrency,
String unitOfMeasureKey)
throws PortalException {
return commerceMoneyFactory.create(
commerceCurrency,
_getBasePrice(
cpInstanceId, commerceCurrency,
CommercePriceListConstants.TYPE_PRICE_LIST, unitOfMeasureKey));
}
@Override
public CommerceMoney getBasePromoPrice(
long cpInstanceId, CommerceCurrency commerceCurrency,
String unitOfMeasureKey)
throws PortalException {
return commerceMoneyFactory.create(
commerceCurrency,
_getBasePrice(
cpInstanceId, commerceCurrency,
CommercePriceListConstants.TYPE_PROMOTION, unitOfMeasureKey));
}
@Override
public CommerceProductPrice getCommerceProductPrice(
CommerceProductPriceRequest commerceProductPriceRequest)
throws PortalException {
long cpInstanceId = commerceProductPriceRequest.getCpInstanceId();
BigDecimal quantity = commerceProductPriceRequest.getQuantity();
String unitOfMeasureKey =
commerceProductPriceRequest.getUnitOfMeasureKey();
CommerceContext commerceContext =
commerceProductPriceRequest.getCommerceContext();
long commercePriceListId = _getCommercePriceListId(
cpInstanceId, commerceProductPriceRequest.getUnitOfMeasureKey(),
commerceContext);
CommercePriceEntry unitCommercePriceEntry = _getUnitPriceEntry(
commercePriceListId, cpInstanceId, unitOfMeasureKey);
BigDecimal unitOfMeasureIncrementalOrderQuantity = BigDecimal.ONE;
if ((unitCommercePriceEntry != null) &&
(unitCommercePriceEntry.getQuantity() != null)) {
unitOfMeasureIncrementalOrderQuantity =
unitCommercePriceEntry.getQuantity();
}
CommerceMoney unitPriceCommerceMoney = _getUnitPriceCommerceMoney(
unitCommercePriceEntry, commercePriceListId, quantity,
commerceContext);
CommerceMoney pricingQuantityUnitPriceCommerceMoney =
_getPricingQuantityUnitPriceCommerceMoney(
unitCommercePriceEntry, commercePriceListId, commerceContext);
boolean priceOnApplication =
unitPriceCommerceMoney.isPriceOnApplication();
BigDecimal finalPrice = unitPriceCommerceMoney.getPrice();
long commercePromoPriceListId = _getCommercePromoPriceListId(
cpInstanceId, commerceContext, unitOfMeasureKey);
CommerceMoney promoPriceCommerceMoney = _getPromoPriceCommerceMoney(
commercePromoPriceListId, cpInstanceId, quantity, unitOfMeasureKey,
commerceContext);
if (!promoPriceCommerceMoney.isEmpty() &&
BigDecimalUtil.gt(
promoPriceCommerceMoney.getPrice(), BigDecimal.ZERO) &&
(BigDecimalUtil.lt(
promoPriceCommerceMoney.getPrice(),
unitPriceCommerceMoney.getPrice()) ||
unitPriceCommerceMoney.isPriceOnApplication())) {
commercePriceListId = commercePromoPriceListId;
finalPrice = promoPriceCommerceMoney.getPrice();
priceOnApplication =
priceOnApplication &&
promoPriceCommerceMoney.isPriceOnApplication();
}
else {
promoPriceCommerceMoney = commerceMoneyFactory.emptyCommerceMoney();
}
BigDecimal[] updatedPrices = getUpdatedPrices(
unitPriceCommerceMoney, promoPriceCommerceMoney, finalPrice,
commerceContext,
commerceProductPriceRequest.getCommerceOptionValues());
finalPrice = updatedPrices[2];
CommerceDiscountValue commerceDiscountValue;
BigDecimal finalPriceWithTaxAmount = getConvertedPrice(
cpInstanceId, finalPrice, false, commerceContext);
boolean discountsTargetNetPrice = true;
CommerceChannel commerceChannel =
commerceChannelLocalService.fetchCommerceChannel(
commerceContext.getCommerceChannelId());
if (commerceChannel != null) {
discountsTargetNetPrice =
commerceChannel.isDiscountsTargetNetPrice();
}
BigDecimal baseQuantity = quantity.divide(
unitOfMeasureIncrementalOrderQuantity, _SCALE,
RoundingMode.HALF_UP);
if (discountsTargetNetPrice) {
commerceDiscountValue = _getCommerceDiscountValue(
cpInstanceId, commercePriceListId, baseQuantity, finalPrice,
unitOfMeasureKey, commerceContext);
finalPrice = finalPrice.multiply(baseQuantity);
if (commerceDiscountValue != null) {
CommerceMoney discountAmountCommerceMoney =
commerceDiscountValue.getDiscountAmount();
finalPrice = finalPrice.subtract(
discountAmountCommerceMoney.getPrice());
}
finalPriceWithTaxAmount = getConvertedPrice(
cpInstanceId, finalPrice, false, commerceContext);
}
else {
commerceDiscountValue = _getCommerceDiscountValue(
cpInstanceId, commercePriceListId, baseQuantity,
finalPriceWithTaxAmount, unitOfMeasureKey, commerceContext);
finalPriceWithTaxAmount = finalPriceWithTaxAmount.multiply(
baseQuantity);
if (commerceDiscountValue != null) {
CommerceMoney discountAmountCommerceMoney =
commerceDiscountValue.getDiscountAmount();
finalPriceWithTaxAmount = finalPriceWithTaxAmount.subtract(
discountAmountCommerceMoney.getPrice());
}
finalPrice = getConvertedPrice(
cpInstanceId, finalPriceWithTaxAmount, true, commerceContext);
}
// fill data
CommerceProductPriceImpl commerceProductPriceImpl =
_getCommerceProductPriceImpl();
commerceProductPriceImpl.setCommercePriceListId(commercePriceListId);
commerceProductPriceImpl.setPriceOnApplication(priceOnApplication);
commerceProductPriceImpl.setPricingQuantityUnitPrice(
pricingQuantityUnitPriceCommerceMoney);
commerceProductPriceImpl.setQuantity(quantity);
commerceProductPriceImpl.setUnitOfMeasureKey(unitOfMeasureKey);
commerceProductPriceImpl.setUnitOfMeasureIncrementalOrderQuantity(
unitOfMeasureIncrementalOrderQuantity);
if (unitPriceCommerceMoney.isEmpty()) {
if (unitPriceCommerceMoney.isPriceOnApplication()) {
commerceProductPriceImpl.setUnitPrice(
commerceMoneyFactory.priceOnApplicationCommerceMoney());
}
else {
commerceProductPriceImpl.setUnitPrice(
commerceMoneyFactory.emptyCommerceMoney());
}
}
else {
commerceProductPriceImpl.setUnitPrice(
commerceMoneyFactory.create(
commerceContext.getCommerceCurrency(), updatedPrices[0]));
}
if (promoPriceCommerceMoney.isEmpty()) {
if (promoPriceCommerceMoney.isPriceOnApplication()) {
commerceProductPriceImpl.setUnitPromoPrice(
commerceMoneyFactory.priceOnApplicationCommerceMoney());
}
else {
if (BigDecimalUtil.gt(updatedPrices[1], BigDecimal.ZERO)) {
commerceProductPriceImpl.setUnitPromoPrice(
commerceMoneyFactory.create(
commerceContext.getCommerceCurrency(),
updatedPrices[1]));
}
else {
commerceProductPriceImpl.setUnitPromoPrice(
commerceMoneyFactory.emptyCommerceMoney());
}
}
}
else {
commerceProductPriceImpl.setUnitPromoPrice(
commerceMoneyFactory.create(
commerceContext.getCommerceCurrency(), updatedPrices[1]));
}
if (discountsTargetNetPrice) {
commerceProductPriceImpl.setCommerceDiscountValue(
commerceDiscountValue);
}
else {
CommerceCurrency commerceCurrency =
commerceContext.getCommerceCurrency();
commerceProductPriceImpl.setCommerceDiscountValue(
CommercePriceConverterUtil.getConvertedCommerceDiscountValue(
commerceDiscountValue,
updatedPrices[2].multiply(baseQuantity), finalPrice,
commerceMoneyFactory,
RoundingMode.valueOf(commerceCurrency.getRoundingMode())));
}
commerceProductPriceImpl.setFinalPrice(
commerceMoneyFactory.create(
commerceContext.getCommerceCurrency(), finalPrice));
if (commerceProductPriceRequest.isCalculateTax() ||
_hasGrossPricePriceList(
cpInstanceId, unitOfMeasureKey, commerceContext)) {
setCommerceProductPriceWithTaxAmount(
cpInstanceId, finalPriceWithTaxAmount, commerceProductPriceImpl,
commerceContext, commerceDiscountValue,
discountsTargetNetPrice);
}
return commerceProductPriceImpl;
}
@Override
public CommerceProductPrice getCommerceProductPrice(
long cpInstanceId, BigDecimal quantity, boolean secure,
String unitOfMeasureKey, CommerceContext commerceContext)
throws PortalException {
CommerceProductPriceRequest commerceProductPriceRequest =
new CommerceProductPriceRequest();
commerceProductPriceRequest.setCommerceContext(commerceContext);
commerceProductPriceRequest.setCommerceOptionValues(
Collections.emptyList());
commerceProductPriceRequest.setCpInstanceId(cpInstanceId);
commerceProductPriceRequest.setQuantity(quantity);
commerceProductPriceRequest.setSecure(secure);
commerceProductPriceRequest.setUnitOfMeasureKey(unitOfMeasureKey);
return getCommerceProductPrice(commerceProductPriceRequest);
}
@Override
public CommerceProductPrice getCommerceProductPrice(
long cpInstanceId, BigDecimal quantity, String unitOfMeasureKey,
CommerceContext commerceContext)
throws PortalException {
return getCommerceProductPrice(
cpInstanceId, quantity, true, unitOfMeasureKey, commerceContext);
}
@Override
public CommerceMoney getFinalPrice(
long cpInstanceId, BigDecimal quantity, boolean secure,
String unitOfMeasureKey, CommerceContext commerceContext)
throws PortalException {
CommerceProductPrice commerceProductPrice = getCommerceProductPrice(
cpInstanceId, quantity, secure, unitOfMeasureKey, commerceContext);
if (commerceProductPrice == null) {
return commerceMoneyFactory.emptyCommerceMoney();
}
if (commerceProductPrice.isPriceOnApplication()) {
return commerceMoneyFactory.priceOnApplicationCommerceMoney();
}
return commerceProductPrice.getFinalPrice();
}
@Override
public CommerceMoney getFinalPrice(
long cpInstanceId, BigDecimal quantity, String unitOfMeasureKey,
CommerceContext commerceContext)
throws PortalException {
return getFinalPrice(
cpInstanceId, quantity, true, unitOfMeasureKey, commerceContext);
}
@Override
public CommerceMoney getPromoPrice(
long cpInstanceId, BigDecimal quantity,
CommerceCurrency commerceCurrency, boolean secure,
String unitOfMeasureKey, CommerceContext commerceContext)
throws PortalException {
return _getPromoPriceCommerceMoney(
_getCommercePromoPriceListId(
cpInstanceId, commerceContext, unitOfMeasureKey),
cpInstanceId, quantity, unitOfMeasureKey, commerceContext);
}
@Override
public CommercePriceEntry getUnitCommercePriceEntry(
CommerceContext commerceContext, long cpInstanceId,
String unitOfMeasureKey)
throws PortalException {
CommercePriceList commercePriceList = _getCommercePriceList(
cpInstanceId, commerceContext,
CommercePriceListConstants.TYPE_PRICE_LIST, unitOfMeasureKey);
long commercePriceListId = 0;
if (commercePriceList != null) {
commercePriceListId = commercePriceList.getCommercePriceListId();
}
CPInstance cpInstance = cpInstanceLocalService.getCPInstance(
cpInstanceId);
CommercePriceEntry commercePriceEntry =
_commercePriceEntryLocalService.fetchCommercePriceEntry(
commercePriceListId, cpInstance.getCPInstanceUuid(),
unitOfMeasureKey, true);
if (commercePriceEntry != null) {
return commercePriceEntry;
}
CommerceCatalog commerceCatalog = cpInstance.getCommerceCatalog();
CommercePriceList basePriceList =
_commercePriceListLocalService.fetchCatalogBaseCommercePriceList(
commerceCatalog.getGroupId());
if (basePriceList != null) {
return _commercePriceEntryLocalService.fetchCommercePriceEntry(
basePriceList.getCommercePriceListId(),
cpInstance.getCPInstanceUuid(), unitOfMeasureKey, true);
}
return null;
}
@Override
public CommerceMoney getUnitMaxPrice(
long cpDefinitionId, BigDecimal quantity, boolean secure,
String unitOfMeasureKey, CommerceContext commerceContext)
throws PortalException {
CommerceMoney commerceMoney = commerceMoneyFactory.emptyCommerceMoney();
List cpInstances =
cpInstanceLocalService.getCPDefinitionInstances(
cpDefinitionId, WorkflowConstants.STATUS_APPROVED,
QueryUtil.ALL_POS, QueryUtil.ALL_POS, null);
for (CPInstance cpInstance : cpInstances) {
CommerceMoney cpInstanceCommerceMoney = getUnitPrice(
cpInstance.getCPInstanceId(), quantity,
commerceContext.getCommerceCurrency(), secure, unitOfMeasureKey,
commerceContext);
if (commerceMoney.isEmpty() ||
BigDecimalUtil.lt(
commerceMoney.getPrice(),
cpInstanceCommerceMoney.getPrice())) {
commerceMoney = cpInstanceCommerceMoney;
}
}
return commerceMoney;
}
@Override
public CommerceMoney getUnitMaxPrice(
long cpDefinitionId, BigDecimal quantity, String unitOfMeasureKey,
CommerceContext commerceContext)
throws PortalException {
return getUnitMaxPrice(
cpDefinitionId, quantity, true, unitOfMeasureKey, commerceContext);
}
@Override
public CommerceMoney getUnitMinPrice(
long cpDefinitionId, BigDecimal quantity, boolean secure,
CommerceContext commerceContext)
throws PortalException {
CommerceMoney commerceMoney = commerceMoneyFactory.emptyCommerceMoney();
List cpInstances =
cpInstanceLocalService.getCPDefinitionInstances(
cpDefinitionId, WorkflowConstants.STATUS_APPROVED,
QueryUtil.ALL_POS, QueryUtil.ALL_POS, null);
for (CPInstance cpInstance : cpInstances) {
List cpInstanceUnitOfMeasures =
_cpInstanceUnitOfMeasureLocalService.
getActiveCPInstanceUnitOfMeasures(
cpInstance.getCPInstanceId());
if (cpInstanceUnitOfMeasures.isEmpty()) {
commerceMoney = _getCommerceMoney(
commerceMoney,
getUnitPrice(
cpInstance.getCPInstanceId(), quantity,
commerceContext.getCommerceCurrency(), secure,
StringPool.BLANK, commerceContext));
}
else {
for (CPInstanceUnitOfMeasure cpInstanceUnitOfMeasure :
cpInstanceUnitOfMeasures) {
commerceMoney = _getCommerceMoney(
commerceMoney,
getUnitPrice(
cpInstance.getCPInstanceId(), quantity,
commerceContext.getCommerceCurrency(), secure,
cpInstanceUnitOfMeasure.getKey(), commerceContext));
}
}
}
return commerceMoney;
}
@Override
public CommerceMoney getUnitMinPrice(
long cpDefinitionId, BigDecimal quantity,
CommerceContext commerceContext)
throws PortalException {
return getUnitMinPrice(cpDefinitionId, quantity, true, commerceContext);
}
@Override
public CommerceMoney getUnitPrice(
long cpInstanceId, BigDecimal quantity,
CommerceCurrency commerceCurrency, boolean secure,
String unitOfMeasureKey, CommerceContext commerceContext)
throws PortalException {
long commercePriceListId = _getCommercePriceListId(
cpInstanceId, unitOfMeasureKey, commerceContext);
return _getUnitPriceCommerceMoney(
_getUnitPriceEntry(
commercePriceListId, cpInstanceId, unitOfMeasureKey),
commercePriceListId, quantity, commerceContext);
}
@Activate
protected void activate(BundleContext bundleContext) {
_serviceTrackerMap = ServiceTrackerMapFactory.openSingleValueMap(
bundleContext, CommercePriceListDiscovery.class, null,
ServiceReferenceMapperFactory.create(
bundleContext,
(commercePriceListDiscovery, emitter) -> emitter.emit(
commercePriceListDiscovery.
getCommercePriceListDiscoveryKey())));
}
@Deactivate
protected void deactivate() {
_serviceTrackerMap.close();
}
private CommerceDiscountValue _calculateCommerceDiscountValue(
BigDecimal[] values, BigDecimal quantity, BigDecimal finalPrice,
CommerceContext commerceContext)
throws PortalException {
CommerceCurrency commerceCurrency =
commerceContext.getCommerceCurrency();
RoundingMode roundingMode = RoundingMode.valueOf(
commerceCurrency.getRoundingMode());
CommerceDiscountApplicationStrategy
commerceDiscountApplicationStrategy =
_getCommerceDiscountApplicationStrategy();
BigDecimal discountedAmount =
commerceDiscountApplicationStrategy.applyCommerceDiscounts(
finalPrice, values);
BigDecimal currentDiscountAmount = finalPrice.subtract(
discountedAmount);
currentDiscountAmount = currentDiscountAmount.setScale(
_SCALE, roundingMode);
CommerceMoney discountAmountCommerceMoney = commerceMoneyFactory.create(
commerceCurrency, currentDiscountAmount.multiply(quantity));
return new CommerceDiscountValue(
0, discountAmountCommerceMoney,
_getDiscountPercentage(discountedAmount, finalPrice, roundingMode),
values);
}
private BigDecimal _getBasePrice(
long cpInstanceId, CommerceCurrency commerceCurrency, String type,
String unitOfMeasureKey)
throws PortalException {
CPInstance cpInstance = cpInstanceLocalService.getCPInstance(
cpInstanceId);
CommercePriceList commercePriceList =
_commercePriceListLocalService.
fetchCatalogBaseCommercePriceListByType(
cpInstance.getGroupId(), type);
if (commercePriceList == null) {
return BigDecimal.ZERO;
}
CommercePriceEntry commercePriceEntry =
_commercePriceEntryLocalService.fetchCommercePriceEntry(
commercePriceList.getCommercePriceListId(),
cpInstance.getCPInstanceUuid(), unitOfMeasureKey, false);
if (commercePriceEntry == null) {
return BigDecimal.ZERO;
}
BigDecimal price = commercePriceEntry.getPrice();
CommerceCurrency priceListCurrency =
commercePriceList.getCommerceCurrency();
if (priceListCurrency.getCommerceCurrencyId() !=
commerceCurrency.getCommerceCurrencyId()) {
price = price.divide(
priceListCurrency.getRate(),
RoundingMode.valueOf(priceListCurrency.getRoundingMode()));
price = price.multiply(commerceCurrency.getRate());
}
return price;
}
private long _getBasePriceListId(CPInstance cpInstance)
throws PortalException {
CommerceCatalog commerceCatalog = cpInstance.getCommerceCatalog();
CommercePriceList basePriceList =
_commercePriceListLocalService.fetchCatalogBaseCommercePriceList(
commerceCatalog.getGroupId());
if (basePriceList != null) {
return basePriceList.getCommercePriceListId();
}
_log.error(
"There is no base price list configured for the current catalog");
return 0;
}
private CommerceDiscountApplicationStrategy
_getCommerceDiscountApplicationStrategy()
throws ConfigurationException {
CommercePricingConfiguration commercePricingConfiguration =
_configurationProvider.getSystemConfiguration(
CommercePricingConfiguration.class);
String commerceDiscountApplicationStrategyKey =
commercePricingConfiguration.commerceDiscountApplicationStrategy();
CommerceDiscountApplicationStrategy
commerceDiscountApplicationStrategy =
_commerceDiscountApplicationStrategyRegistry.get(
commerceDiscountApplicationStrategyKey);
if (commerceDiscountApplicationStrategy == null) {
if (_log.isWarnEnabled()) {
_log.warn(
"No commerce discount application strategy specified for " +
commerceDiscountApplicationStrategyKey);
}
}
return commerceDiscountApplicationStrategy;
}
private CommerceDiscountValue _getCommerceDiscountValue(
long cpInstanceId, long commercePriceListId, BigDecimal quantity,
BigDecimal finalPrice, String unitOfMeasureKey,
CommerceContext commerceContext)
throws PortalException {
if ((finalPrice == null) ||
BigDecimalUtil.lte(finalPrice, BigDecimal.ZERO)) {
return null;
}
CPInstance cpInstance = cpInstanceLocalService.getCPInstance(
cpInstanceId);
CommercePriceEntry commercePriceEntry =
_commercePriceEntryLocalService.fetchCommercePriceEntry(
commercePriceListId, cpInstance.getCPInstanceUuid(),
unitOfMeasureKey, true);
if (commercePriceEntry == null) {
return _commerceDiscountCalculation.getProductCommerceDiscountValue(
cpInstanceId, quantity, finalPrice, unitOfMeasureKey,
commerceContext);
}
BigDecimal[] values = new BigDecimal[4];
if (!commercePriceEntry.isHasTierPrice() &&
!commercePriceEntry.isDiscountDiscovery()) {
values[0] = commercePriceEntry.getDiscountLevel1();
values[1] = commercePriceEntry.getDiscountLevel2();
values[2] = commercePriceEntry.getDiscountLevel3();
values[3] = commercePriceEntry.getDiscountLevel4();
return _calculateCommerceDiscountValue(
values, quantity, finalPrice, commerceContext);
}
if (!commercePriceEntry.isBulkPricing()) {
return _commerceDiscountCalculation.getProductCommerceDiscountValue(
cpInstanceId, quantity, finalPrice, unitOfMeasureKey,
commerceContext);
}
CommerceTierPriceEntry commerceTierPriceEntry =
_commerceTierPriceEntryLocalService.
fetchClosestCommerceTierPriceEntry(
commercePriceEntry.getCommercePriceEntryId(), quantity);
if ((commerceTierPriceEntry == null) ||
commerceTierPriceEntry.isDiscountDiscovery()) {
return _commerceDiscountCalculation.getProductCommerceDiscountValue(
cpInstanceId, quantity, finalPrice, unitOfMeasureKey,
commerceContext);
}
values[0] = commerceTierPriceEntry.getDiscountLevel1();
values[1] = commerceTierPriceEntry.getDiscountLevel2();
values[2] = commerceTierPriceEntry.getDiscountLevel3();
values[3] = commerceTierPriceEntry.getDiscountLevel4();
return _calculateCommerceDiscountValue(
values, quantity, finalPrice, commerceContext);
}
private CommerceMoney _getCommerceMoney(
CommerceMoney commerceMoney, CommerceMoney cpInstanceCommerceMoney) {
if (commerceMoney.isEmpty()) {
commerceMoney = cpInstanceCommerceMoney;
}
else if (!cpInstanceCommerceMoney.isPriceOnApplication() &&
BigDecimalUtil.gt(
commerceMoney.getPrice(),
cpInstanceCommerceMoney.getPrice())) {
commerceMoney = cpInstanceCommerceMoney;
}
return commerceMoney;
}
private CommerceMoney _getCommerceMoney(
long commercePriceListId, CommerceCurrency commerceCurrency,
BigDecimal price)
throws PortalException {
CommercePriceList commercePriceList =
_commercePriceListLocalService.getCommercePriceList(
commercePriceListId);
CommerceCurrency priceListCurrency =
_commerceCurrencyLocalService.getCommerceCurrency(
commercePriceList.getCompanyId(),
commercePriceList.getCommerceCurrencyCode());
if (priceListCurrency.getCommerceCurrencyId() !=
commerceCurrency.getCommerceCurrencyId()) {
price = price.divide(
priceListCurrency.getRate(),
RoundingMode.valueOf(priceListCurrency.getRoundingMode()));
price = price.multiply(commerceCurrency.getRate());
}
if (price != null) {
return commerceMoneyFactory.create(commerceCurrency, price);
}
return commerceMoneyFactory.emptyCommerceMoney();
}
private BigDecimal _getCommercePrice(
long commercePriceListId, CommercePriceEntry commercePriceEntry,
BigDecimal quantity)
throws PortalException {
if (commercePriceEntry == null) {
return null;
}
BigDecimal commercePrice = commercePriceEntry.getPrice();
CommercePriceList commercePriceList =
_commercePriceListLocalService.getCommercePriceList(
commercePriceEntry.getCommercePriceListId());
CommercePriceList modifierCommercePriceList =
_commercePriceListLocalService.getCommercePriceList(
commercePriceListId);
CommerceCurrency commerceCurrency =
_commerceCurrencyLocalService.getCommerceCurrency(
commercePriceList.getCompanyId(),
commercePriceList.getCommerceCurrencyCode());
CPInstance cpInstance = _cpInstanceLocalService.fetchCProductInstance(
commercePriceEntry.getCProductId(),
commercePriceEntry.getCPInstanceUuid());
if ((cpInstance != null) && !commercePriceEntry.isHasTierPrice()) {
if ((commercePriceEntry.getCommercePriceListId() !=
commercePriceListId) &&
(commercePriceList.isNetPrice() ==
modifierCommercePriceList.isNetPrice())) {
commercePrice =
_commercePriceModifierHelper.applyCommercePriceModifier(
commercePriceListId, cpInstance.getCPDefinitionId(),
commercePriceEntry.getPriceCommerceMoney(
commerceCurrency.getCommerceCurrencyId()));
}
return commercePrice;
}
if (commercePriceEntry.isBulkPricing()) {
CommerceTierPriceEntry commerceTierPriceEntry =
_commerceTierPriceEntryLocalService.
fetchClosestCommerceTierPriceEntry(
commercePriceEntry.getCommercePriceEntryId(), quantity);
if (commerceTierPriceEntry == null) {
return commercePriceEntry.getPrice();
}
if ((cpInstance != null) &&
(commercePriceEntry.getCommercePriceListId() !=
commercePriceListId) &&
(commercePriceList.isNetPrice() ==
modifierCommercePriceList.isNetPrice())) {
return _commercePriceModifierHelper.applyCommercePriceModifier(
commercePriceListId, cpInstance.getCPDefinitionId(),
commerceTierPriceEntry.getPriceCommerceMoney(
commerceCurrency.getCommerceCurrencyId()));
}
return commerceTierPriceEntry.getPrice();
}
if ((commercePriceEntry.getCommercePriceListId() !=
commercePriceListId) &&
(commercePriceList.isNetPrice() ==
modifierCommercePriceList.isNetPrice())) {
return _commercePriceModifierHelper.applyCommercePriceModifier(
commercePriceListId, cpInstance.getCPDefinitionId(),
commerceMoneyFactory.create(commerceCurrency, commercePrice));
}
List commerceTierPriceEntries =
_commerceTierPriceEntryLocalService.getCommerceTierPriceEntries(
commercePriceEntry.getCommercePriceEntryId(), quantity);
if (commerceTierPriceEntries.isEmpty()) {
return commercePrice;
}
commercePrice = BigDecimal.ZERO;
CommerceTierPriceEntry commerceTierPriceEntry1 =
commerceTierPriceEntries.get(0);
BigDecimal totalTierCounter = BigDecimal.ZERO;
BigDecimal minQuantity1 = commerceTierPriceEntry1.getMinQuantity();
BigDecimal tierCounter = minQuantity1.subtract(
totalTierCounter.add(BigDecimal.ONE));
BigDecimal currentPrice = commercePriceEntry.getPrice();
currentPrice = currentPrice.multiply(tierCounter);
commercePrice = commercePrice.add(currentPrice);
totalTierCounter = totalTierCounter.add(tierCounter);
for (int i = 0; i < (commerceTierPriceEntries.size() - 1); i++) {
CommerceTierPriceEntry commerceTierPriceEntry2 =
commerceTierPriceEntries.get(i);
currentPrice = commerceTierPriceEntry2.getPrice();
CommerceTierPriceEntry commerceTierPriceEntry3 =
commerceTierPriceEntries.get(i + 1);
BigDecimal minQuantity = commerceTierPriceEntry3.getMinQuantity();
tierCounter = minQuantity.subtract(
totalTierCounter.add(BigDecimal.ONE));
currentPrice = currentPrice.multiply(tierCounter);
commercePrice = commercePrice.add(currentPrice);
totalTierCounter = totalTierCounter.add(tierCounter);
}
totalTierCounter = quantity.subtract(totalTierCounter);
CommerceTierPriceEntry commerceTierPriceEntry2 =
commerceTierPriceEntries.get(commerceTierPriceEntries.size() - 1);
currentPrice = commerceTierPriceEntry2.getPrice();
currentPrice = currentPrice.multiply(totalTierCounter);
commercePrice = commercePrice.add(currentPrice);
RoundingMode roundingMode = RoundingMode.valueOf(
commerceCurrency.getRoundingMode());
return commercePrice.divide(quantity, _SCALE, roundingMode);
}
private BigDecimal _getCommercePrice(
long cpInstanceId, long commercePriceListId,
CommerceMoney unitPriceCommerceMoney)
throws PortalException {
CommercePriceList commercePriceList =
_commercePriceListLocalService.fetchCommercePriceList(
commercePriceListId);
if (commercePriceList == null) {
return null;
}
CPInstance cpInstance = cpInstanceLocalService.getCPInstance(
cpInstanceId);
return _commercePriceModifierHelper.applyCommercePriceModifier(
commercePriceListId, cpInstance.getCPDefinitionId(),
unitPriceCommerceMoney);
}
private CommercePriceList _getCommercePriceList(
long cpInstanceId, CommerceContext commerceContext, String type,
String unitOfMeasureKey)
throws PortalException {
long commerceAccountId = CommerceUtil.getCommerceAccountId(
commerceContext);
CommerceChannelAccountEntryRel commerceChannelAccountEntryRel =
commerceChannelAccountEntryRelLocalService.
fetchCommerceChannelAccountEntryRel(
commerceAccountId, commerceContext.getCommerceChannelId(),
CommerceChannelAccountEntryRelConstants.TYPE_PRICE_LIST);
if ((commerceChannelAccountEntryRel != null) &&
commerceChannelAccountEntryRel.isOverrideEligibility()) {
return _commercePriceListLocalService.getCommercePriceList(
commerceChannelAccountEntryRel.getClassPK());
}
CommercePriceListDiscovery commercePriceListDiscovery =
_getCommercePriceListDiscovery(type);
if (commercePriceListDiscovery == null) {
return null;
}
CPInstance cpInstance = cpInstanceLocalService.getCPInstance(
cpInstanceId);
CommerceOrder commerceOrder = commerceContext.getCommerceOrder();
long commerceOrderTypeId = 0;
if (commerceOrder != null) {
commerceOrderTypeId = commerceOrder.getCommerceOrderTypeId();
}
return commercePriceListDiscovery.getCommercePriceList(
cpInstance.getGroupId(), commerceAccountId,
commerceContext.getCommerceChannelId(), commerceOrderTypeId,
cpInstance.getCPInstanceUuid(), type, unitOfMeasureKey);
}
private CommercePriceListDiscovery _getCommercePriceListDiscovery(
String type)
throws PortalException {
CommercePricingConfiguration commercePricingConfiguration =
_configurationProvider.getSystemConfiguration(
CommercePricingConfiguration.class);
String discoveryMethod = CommercePricingConstants.ORDER_BY_HIERARCHY;
if (type.equals(CommercePriceListConstants.TYPE_PRICE_LIST)) {
discoveryMethod =
commercePricingConfiguration.commercePriceListDiscovery();
}
else if (type.equals(CommercePriceListConstants.TYPE_PROMOTION)) {
discoveryMethod =
commercePricingConfiguration.commercePromotionDiscovery();
}
CommercePriceListDiscovery commercePriceListDiscovery =
_serviceTrackerMap.getService(discoveryMethod);
if (commercePriceListDiscovery == null) {
if (_log.isWarnEnabled()) {
_log.warn(
"No commerce price list discovery specified for " +
discoveryMethod);
}
}
return commercePriceListDiscovery;
}
private long _getCommercePriceListId(
long cpInstanceId, String unitOfMeasureKey,
CommerceContext commerceContext)
throws PortalException {
CommercePriceList commercePriceList = _getCommercePriceList(
cpInstanceId, commerceContext,
CommercePriceListConstants.TYPE_PRICE_LIST, unitOfMeasureKey);
long commercePriceListId = 0;
if (commercePriceList != null) {
commercePriceListId = commercePriceList.getCommercePriceListId();
}
CPInstance cpInstance = cpInstanceLocalService.getCPInstance(
cpInstanceId);
CommercePriceEntry commercePriceEntry =
_commercePriceEntryLocalService.fetchCommercePriceEntry(
commercePriceListId, cpInstance.getCPInstanceUuid(),
unitOfMeasureKey, true);
if (commercePriceEntry != null) {
return commercePriceEntry.getCommercePriceListId();
}
boolean hasCommercePriceModifiers =
_commercePriceModifierHelper.hasCommercePriceModifiers(
commercePriceListId, cpInstance.getCPDefinitionId());
if (hasCommercePriceModifiers) {
return commercePriceListId;
}
return _getBasePriceListId(cpInstance);
}
private CommerceProductPriceImpl _getCommerceProductPriceImpl() {
CommerceProductPriceImpl commerceProductPriceImpl =
new CommerceProductPriceImpl();
commerceProductPriceImpl.setFinalPrice(
commerceMoneyFactory.emptyCommerceMoney());
commerceProductPriceImpl.setFinalPriceWithTaxAmount(
commerceMoneyFactory.emptyCommerceMoney());
commerceProductPriceImpl.setPriceOnApplication(false);
commerceProductPriceImpl.setUnitPrice(
commerceMoneyFactory.emptyCommerceMoney());
commerceProductPriceImpl.setUnitPriceWithTaxAmount(
commerceMoneyFactory.emptyCommerceMoney());
commerceProductPriceImpl.setUnitPromoPrice(
commerceMoneyFactory.emptyCommerceMoney());
commerceProductPriceImpl.setUnitPromoPriceWithTaxAmount(
commerceMoneyFactory.emptyCommerceMoney());
return commerceProductPriceImpl;
}
private long _getCommercePromoPriceListId(
long cpInstanceId, CommerceContext commerceContext,
String unitOfMeasureKey)
throws PortalException {
CommercePriceList commercePriceList = _getCommercePriceList(
cpInstanceId, commerceContext,
CommercePriceListConstants.TYPE_PROMOTION, unitOfMeasureKey);
if (commercePriceList != null) {
return commercePriceList.getCommercePriceListId();
}
return 0;
}
private BigDecimal _getDiscountPercentage(
BigDecimal discountedAmount, BigDecimal amount,
RoundingMode roundingMode) {
double actualPrice = discountedAmount.doubleValue();
double originalPrice = amount.doubleValue();
double percentage = actualPrice / originalPrice;
BigDecimal discountPercentage = new BigDecimal(percentage);
discountPercentage = discountPercentage.multiply(_ONE_HUNDRED);
MathContext mathContext = new MathContext(
discountPercentage.precision(), roundingMode);
return _ONE_HUNDRED.subtract(discountPercentage, mathContext);
}
private CommerceMoney _getPricingQuantityUnitPriceCommerceMoney(
CommercePriceEntry commercePriceEntry, long commercePriceListId,
CommerceContext commerceContext)
throws PortalException {
if (commercePriceEntry == null) {
return commerceMoneyFactory.create(
commerceContext.getCommerceCurrency(), BigDecimal.ZERO);
}
BigDecimal pricingQuantity = commercePriceEntry.getPricingQuantity();
if ((pricingQuantity == null) ||
BigDecimalUtil.lte(pricingQuantity, BigDecimal.ZERO)) {
return commerceMoneyFactory.emptyCommerceMoney();
}
CommerceCurrency commerceCurrency =
commerceContext.getCommerceCurrency();
BigDecimal pricingQuantityUnitPrice = pricingQuantity.multiply(
commercePriceEntry.getPrice()
).divide(
commercePriceEntry.getQuantity(),
commerceCurrency.getMaxFractionDigits(),
RoundingMode.valueOf(commerceCurrency.getRoundingMode())
);
CommercePriceList commercePriceList =
_commercePriceListLocalService.getCommercePriceList(
commercePriceListId);
if (!commercePriceList.isNetPrice()) {
CPInstance cpInstance =
_cpInstanceLocalService.fetchCProductInstance(
commercePriceEntry.getCProductId(),
commercePriceEntry.getCPInstanceUuid());
if (cpInstance != null) {
pricingQuantityUnitPrice = getConvertedPrice(
cpInstance.getCPInstanceId(), pricingQuantityUnitPrice,
true, commerceContext);
}
}
return _getCommerceMoney(
commercePriceEntry.getCommercePriceListId(),
commerceContext.getCommerceCurrency(), pricingQuantityUnitPrice);
}
private CommerceMoney _getPromoPriceCommerceMoney(
long commercePriceListId, long cpInstanceId, BigDecimal quantity,
String unitOfMeasureKey, CommerceContext commerceContext)
throws PortalException {
if (commercePriceListId <= 0) {
return commerceMoneyFactory.emptyCommerceMoney();
}
CPInstance cpInstance = cpInstanceLocalService.getCPInstance(
cpInstanceId);
CommercePriceList commercePriceList =
_commercePriceListLocalService.getCommercePriceList(
commercePriceListId);
CommercePriceEntry commercePriceEntry =
_commercePriceEntryLocalService.fetchCommercePriceEntry(
commercePriceListId, cpInstance.getCPInstanceUuid(),
unitOfMeasureKey, true);
if (commercePriceEntry != null) {
if (commercePriceEntry.isPriceOnApplication()) {
return commerceMoneyFactory.priceOnApplicationCommerceMoney();
}
BigDecimal promoPrice = _getCommercePrice(
commercePriceListId, commercePriceEntry, quantity);
if (!commercePriceList.isNetPrice()) {
promoPrice = getConvertedPrice(
cpInstance.getCPInstanceId(), promoPrice, true,
commerceContext);
}
return _getCommerceMoney(
commercePriceListId, commerceContext.getCommerceCurrency(),
promoPrice);
}
if (!_commercePriceModifierHelper.hasCommercePriceModifiers(
commercePriceListId, cpInstance.getCPDefinitionId())) {
return commerceMoneyFactory.emptyCommerceMoney();
}
CommerceMoney unitPriceCommerceMoney = getUnitPrice(
cpInstanceId, quantity, commerceContext.getCommerceCurrency(),
false, unitOfMeasureKey, commerceContext);
if (unitPriceCommerceMoney.isPriceOnApplication()) {
return commerceMoneyFactory.priceOnApplicationCommerceMoney();
}
BigDecimal promoPrice = _getCommercePrice(
cpInstanceId, commercePriceListId, unitPriceCommerceMoney);
if (!commercePriceList.isNetPrice()) {
promoPrice = getConvertedPrice(
cpInstance.getCPInstanceId(), promoPrice, true,
commerceContext);
}
return _getCommerceMoney(
commercePriceListId, commerceContext.getCommerceCurrency(),
promoPrice);
}
private CommerceMoney _getUnitPriceCommerceMoney(
CommercePriceEntry commercePriceEntry, long commercePriceListId,
BigDecimal quantity, CommerceContext commerceContext)
throws PortalException {
if (commercePriceEntry == null) {
return commerceMoneyFactory.create(
commerceContext.getCommerceCurrency(), BigDecimal.ZERO);
}
if (commercePriceEntry.isPriceOnApplication()) {
return commerceMoneyFactory.priceOnApplicationCommerceMoney();
}
BigDecimal unitPrice = _getCommercePrice(
commercePriceListId, commercePriceEntry, quantity);
CommercePriceList commercePriceList =
_commercePriceListLocalService.getCommercePriceList(
commercePriceListId);
if (!commercePriceList.isNetPrice()) {
CPInstance cpInstance =
_cpInstanceLocalService.fetchCProductInstance(
commercePriceEntry.getCProductId(),
commercePriceEntry.getCPInstanceUuid());
if (cpInstance != null) {
unitPrice = getConvertedPrice(
cpInstance.getCPInstanceId(), unitPrice, true,
commerceContext);
}
}
return _getCommerceMoney(
commercePriceEntry.getCommercePriceListId(),
commerceContext.getCommerceCurrency(), unitPrice);
}
private CommercePriceEntry _getUnitPriceEntry(
long commercePriceListId, long cpInstanceId,
String unitOfMeasureKey)
throws PortalException {
if (commercePriceListId == 0) {
return null;
}
CommercePriceList commercePriceList =
_commercePriceListLocalService.getCommercePriceList(
commercePriceListId);
CPInstance cpInstance = cpInstanceLocalService.getCPInstance(
cpInstanceId);
CommercePriceEntry commercePriceEntry =
_commercePriceEntryLocalService.fetchCommercePriceEntry(
commercePriceList.getCommercePriceListId(),
cpInstance.getCPInstanceUuid(), unitOfMeasureKey, true);
if (commercePriceEntry != null) {
return commercePriceEntry;
}
return _commercePriceEntryLocalService.fetchCommercePriceEntry(
_getBasePriceListId(cpInstance), cpInstance.getCPInstanceUuid(),
unitOfMeasureKey, false);
}
private boolean _hasGrossPricePriceList(
long cpInstanceId, String unitOfMeasureKey,
CommerceContext commerceContext)
throws PortalException {
CommercePriceList commercePriceList =
_commercePriceListLocalService.fetchCommercePriceList(
_getCommercePriceListId(
cpInstanceId, unitOfMeasureKey, commerceContext));
if ((commercePriceList != null) && !commercePriceList.isNetPrice()) {
return true;
}
CommercePriceList commercePromoPriceList =
_commercePriceListLocalService.fetchCommercePriceList(
_getCommercePromoPriceListId(
cpInstanceId, commerceContext, unitOfMeasureKey));
if ((commercePromoPriceList != null) &&
!commercePromoPriceList.isNetPrice()) {
return true;
}
return false;
}
private static final BigDecimal _ONE_HUNDRED = BigDecimal.valueOf(100);
private static final int _SCALE = 10;
private static final Log _log = LogFactoryUtil.getLog(
CommerceProductPriceCalculationV2Impl.class);
@Reference
private CommerceCurrencyLocalService _commerceCurrencyLocalService;
@Reference
private CommerceDiscountApplicationStrategyRegistry
_commerceDiscountApplicationStrategyRegistry;
@Reference
private CommerceDiscountCalculation _commerceDiscountCalculation;
@Reference
private CommercePriceEntryLocalService _commercePriceEntryLocalService;
@Reference
private CommercePriceListLocalService _commercePriceListLocalService;
@Reference
private CommercePriceModifierHelper _commercePriceModifierHelper;
@Reference
private CommerceTierPriceEntryLocalService
_commerceTierPriceEntryLocalService;
@Reference
private ConfigurationProvider _configurationProvider;
@Reference
private CPInstanceLocalService _cpInstanceLocalService;
@Reference
private CPInstanceUnitOfMeasureLocalService
_cpInstanceUnitOfMeasureLocalService;
private ServiceTrackerMap
_serviceTrackerMap;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy