Hi everyone,
We’re building a Liferay Commerce portal where products are coming from an external PIM system. Such products are saved in Liferay as normal Commerce Products, and can be added to Cart / ordered during Checkout.
But we have also another type of products - Spare Parts. Each machine product (e.g. drill / saw / etc.) has a spare parts diagram, where users can order required parts. Data for spare parts diagram (product codes / titles / etc.) is also coming from external system. But there are no corresponding Commerce Product in Liferay (there are not coming from PIM).
The questions is: can I add such products as CommerceOrderItem to cart (using data from spare part drawing), and order them during checkout?
Note: we’re not using Liferay Prices, instead product prices are fetched from external ERP.
I’m trying to add CommerceOrderItem using the spare parts data, e.g.:
long commerceOrderItemId = counterLocalService.increment();
CommerceOrderItem orderItem = commerceOrderItemLocalService.createCommerceOrderItem(commerceOrderItemId);
//...
orderItem.setCommerceOrderId(cart.getId()); orderItem.setQuantity(BigDecimal.valueOf(sparePartItem.getQuantity()));
orderItem.setSku(sparePartItem.getProductCode());
orderItem.setName(sparePartItem.getProductTitle(), cartContext.getLocale());
commerceOrderItemLocalService.addCommerceOrderItem(orderItem);
(CProductId / CPInstanceId are 0 in this case, as there is no corresponding CommerceProduct).
In general is works, and I can see products in Cart…
But if I try to add another (regular) Product, or update any Product - I get exceptions related to missing products, e.g.:
Caused by: java.lang.NullPointerException: Cannot read field "intCompact" because "augend" is null
at java.math.BigDecimal.add(BigDecimal.java:1385) ~[?:?]
at com.liferay.commerce.internal.price.CommerceOrderPriceCalculationV2Impl.getSubtotal(CommerceOrderPriceCalculationV2Impl.java:357) ~[?:?]
at com.liferay.commerce.internal.price.CommerceOrderPriceCalculationV2Impl.getCommerceOrderPrice(CommerceOrderPriceCalculationV2Impl.java:73) ~[?:?]
at com.liferay.commerce.service.impl.CommerceOrderLocalServiceImpl.recalculatePrice(CommerceOrderLocalServiceImpl.java:972) ~[?:?]
at jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
at java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
at com.liferay.portal.spring.aop.AopMethodInvocationImpl.proceed(AopMethodInvocationImpl.java:41) ~[portal-impl.jar:?]
at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:60) ~[portal-impl.jar:?]
at com.liferay.portal.spring.aop.AopMethodInvocationImpl.proceed(AopMethodInvocationImpl.java:48) ~[portal-impl.jar:?]
at com.liferay.portal.kernel.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:55) ~[portal-kernel.jar:?]
at com.liferay.portal.spring.aop.AopMethodInvocationImpl.proceed(AopMethodInvocationImpl.java:48) ~[portal-impl.jar:?]
at com.liferay.change.tracking.internal.aop.CTTransactionAdvice.invoke(CTTransactionAdvice.java:70) ~[?:?]
at com.liferay.portal.spring.aop.AopMethodInvocationImpl.proceed(AopMethodInvocationImpl.java:48) ~[portal-impl.jar:?]
at com.liferay.portal.spring.aop.AopInvocationHandler.invoke(AopInvocationHandler.java:40) ~[portal-impl.jar:?]
at jdk.proxy37.$Proxy1277.recalculatePrice(Unknown Source) ~[?:?]
at com.liferay.commerce.service.impl.CommerceOrderItemLocalServiceImpl.addCommerceOrderItem(CommerceOrderItemLocalServiceImpl.java:246) ~[?:?]
or
Caused by: com.liferay.commerce.product.exception.NoSuchCPInstanceException: No CPInstance exists with the primary key 0
at com.liferay.commerce.product.service.persistence.impl.CPInstancePersistenceImpl.findByPrimaryKey(CPInstancePersistenceImpl.java:8893) ~[?:?]
at com.liferay.commerce.product.service.persistence.impl.CPInstancePersistenceImpl.findByPrimaryKey(CPInstancePersistenceImpl.java:8911) ~[?:?]
at com.liferay.commerce.product.service.base.CPInstanceLocalServiceBaseImpl.getCPInstance(CPInstanceLocalServiceBaseImpl.java:300) ~[?:?]
at jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
at java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
at com.liferay.portal.spring.aop.AopMethodInvocationImpl.proceed(AopMethodInvocationImpl.java:41) ~[portal-impl.jar:?]
at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:60) ~[portal-impl.jar:?]
at com.liferay.portal.spring.aop.AopMethodInvocationImpl.proceed(AopMethodInvocationImpl.java:48) ~[portal-impl.jar:?]
at com.liferay.portal.spring.aop.AopInvocationHandler.invoke(AopInvocationHandler.java:40) ~[portal-impl.jar:?]
at jdk.proxy333.$Proxy935.getCPInstance(Unknown Source) ~[?:?]
at com.liferay.commerce.internal.price.CommerceProductPriceCalculationV2Impl._getCommercePriceList(CommerceProductPriceCalculationV2Impl.java:996) ~[?:?]
at com.liferay.commerce.internal.price.CommerceProductPriceCalculationV2Impl._getCommercePriceListId(CommerceProductPriceCalculationV2Impl.java:1051) ~[?:?]
at com.liferay.commerce.internal.price.CommerceProductPriceCalculationV2Impl.getCommerceProductPrice(CommerceProductPriceCalculationV2Impl.java:114) ~[?:?]
at com.liferay.commerce.service.impl.CommerceOrderItemLocalServiceImpl._getCommerceProductPrice(CommerceOrderItemLocalServiceImpl.java:1546) ~[?:?]
at com.liferay.commerce.service.impl.CommerceOrderItemLocalServiceImpl._updateCommerceOrderItem(CommerceOrderItemLocalServiceImpl.java:2442) ~[?:?]
at com.liferay.commerce.service.impl.CommerceOrderItemLocalServiceImpl.updateCommerceOrderItem(CommerceOrderItemLocalServiceImpl.java:841) ~[?:?]
at jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
at java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
at com.liferay.portal.spring.aop.AopMethodInvocationImpl.proceed(AopMethodInvocationImpl.java:41) ~[portal-impl.jar:?]
at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:60) ~[portal-impl.jar:?]
at com.liferay.portal.spring.aop.AopMethodInvocationImpl.proceed(AopMethodInvocationImpl.java:48) ~[portal-impl.jar:?]
at com.liferay.portal.service.ServiceContextAdvice.invoke(ServiceContextAdvice.java:51) ~[portal-impl.jar:?]
at com.liferay.portal.spring.aop.AopMethodInvocationImpl.proceed(AopMethodInvocationImpl.java:48) ~[portal-impl.jar:?]
at com.liferay.portal.kernel.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:55) ~[portal-kernel.jar:?]
at com.liferay.portal.spring.aop.AopMethodInvocationImpl.proceed(AopMethodInvocationImpl.java:48) ~[portal-impl.jar:?]
at com.liferay.change.tracking.internal.aop.CTTransactionAdvice.invoke(CTTransactionAdvice.java:70) ~[?:?]
at com.liferay.portal.spring.aop.AopMethodInvocationImpl.proceed(AopMethodInvocationImpl.java:48) ~[portal-impl.jar:?]
at com.liferay.portal.spring.aop.AopInvocationHandler.invoke(AopInvocationHandler.java:40) ~[portal-impl.jar:?]
at jdk.proxy37.$Proxy1232.updateCommerceOrderItem(Unknown Source) ~[?:?]
at com.liferay.commerce.service.impl.CommerceOrderItemLocalServiceImpl.updateCommerceOrderItem(CommerceOrderItemLocalServiceImpl.java:777) ~[?:?]
Both errors are related to Liferay attempts for price calculation. But, as we don’t need Liferay Prices - is there a way to bypass this logic?
More generic question: does Liferay support Cart Items w/o Products at all? AFAIK, it should - but seems not working as expected.
Regards,
Vitaliy
Hi Vitaly, Indeed, OOTB, the product needs to exist in Liferay. I was wondering if it would be possible to import these products into the platform. Without them there, we lose the ability to track order history and take advantage of all the OOTB features available. What do you think?
– RoselaineMarquesI even asked the same question to someone from Commerce team on last Devcon - the answer was that it should be possible. I only tried briefly but I failed. What we do and what has worked for us for last few years is to create product the moment we are adding it to the cart. So the list of products is displayed from remote API but then we add necessary data (like CPInstance). This way we can make orders and use other commerce capabilities. It’s not perfect, I would also prefer to just add remote items to cart directly but at least it works.
– RafalPydyniak