This is an automated email from the ASF dual-hosted git repository. mbrohl pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git
The following commit(s) were added to refs/heads/trunk by this push: new 3d349c4870 Fixed: Persist OrderItemAttribute of ShoppingCartItem (OFBIZ-12828) 3d349c4870 is described below commit 3d349c48708723e99220858cc45b8f392ec50eaf Author: Sebastian Berg <sebastian.b...@ecomify.de> AuthorDate: Thu Jul 27 15:52:48 2023 +0200 Fixed: Persist OrderItemAttribute of ShoppingCartItem (OFBIZ-12828) Fix introduced so that OrderItemAttributes are persisted inside ShoppingCartItemAttributes from now on. Checkstyle ParameterNumber needed to be increased by one --- .../datamodel/entitydef/order-entitymodel.xml | 15 +++ .../order/servicedef/services_shoppinglist.xml | 1 + .../shoppinglist/ShoppingListServicesScript.groovy | 61 +++++++----- .../ofbiz/order/shoppingcart/ShoppingCart.java | 7 -- .../ofbiz/order/shoppingcart/ShoppingCartItem.java | 109 ++++++++++++++++----- .../order/shoppinglist/ShoppingListEvents.java | 74 ++++++++++++-- config/checkstyle/checkstyle.xml | 2 +- 7 files changed, 199 insertions(+), 70 deletions(-) diff --git a/applications/datamodel/entitydef/order-entitymodel.xml b/applications/datamodel/entitydef/order-entitymodel.xml index 5bb9f6c56d..f827711b7a 100644 --- a/applications/datamodel/entitydef/order-entitymodel.xml +++ b/applications/datamodel/entitydef/order-entitymodel.xml @@ -2951,6 +2951,21 @@ under the License. <key-map field-name="productId"/> </relation> </entity> + <entity entity-name="ShoppingListItemAttribute" + package-name="org.ofbiz.order.shoppinglist" + title="Shopping List Item Attribute Entity"> + <field name="shoppingListId" type="id"></field> + <field name="shoppingListItemSeqId" type="id"></field> + <field name="attrName" type="id-long"></field> + <field name="attrValue" type="value"></field> + <prim-key field="shoppingListId"/> + <prim-key field="shoppingListItemSeqId"/> + <prim-key field="attrName"/> + <relation type="one" fk-name="SHLIST_ITEM_ATTR" rel-entity-name="ShoppingListItem"> + <key-map field-name="shoppingListId"/> + <key-map field-name="shoppingListItemSeqId"/> + </relation> + </entity> <entity entity-name="ShoppingListItemSurvey" package-name="org.apache.ofbiz.order.shoppinglist" title="Shopping List Item"> diff --git a/applications/order/servicedef/services_shoppinglist.xml b/applications/order/servicedef/services_shoppinglist.xml index 947ee8f707..8e46990395 100644 --- a/applications/order/servicedef/services_shoppinglist.xml +++ b/applications/order/servicedef/services_shoppinglist.xml @@ -124,6 +124,7 @@ under the License. <attribute name="shoppingListId" type="String" mode="IN" optional="true"/> <attribute name="productStoreId" type="String" mode="INOUT" optional="true"/> <attribute name="productId" type="String" mode="IN" optional="false"/> + <attribute name="shoppingListItemAttributes" type="Map" mode="IN" optional="true"/> <attribute name="shoppingListItemSeqId" type="String" mode="OUT" optional="false"/> </service> <service name="updateShoppingListItem" engine="groovy" auth="true" diff --git a/applications/order/src/main/groovy/org/apache/ofbiz/order/shoppinglist/ShoppingListServicesScript.groovy b/applications/order/src/main/groovy/org/apache/ofbiz/order/shoppinglist/ShoppingListServicesScript.groovy index 8333299b71..72f151b2f9 100644 --- a/applications/order/src/main/groovy/org/apache/ofbiz/order/shoppinglist/ShoppingListServicesScript.groovy +++ b/applications/order/src/main/groovy/org/apache/ofbiz/order/shoppinglist/ShoppingListServicesScript.groovy @@ -73,41 +73,50 @@ Map updateShoppingList() { /** * Create a ShoppingList Item + * @return */ Map createShoppingListItem() { Map result = success() List shoppingListItems = from('ShoppingListItem') .where(productId: parameters.productId, - shoppingListId: parameters.shoppingListId) + shoppingListId: parameters.shoppingListId) .queryList() + // Check if we have a matching ShoppingListItem (with equal ShoppingListItemAttributes!) and update its quantity if (shoppingListItems) { - GenericValue shoppingListItem = shoppingListItems[0] - - shoppingListItem.quantity = shoppingListItem.quantity ?: 0.0 - parameters.quantity = parameters.quantity ?: 0.0 - - BigDecimal totalQty = shoppingListItem.quantity + parameters.quantity - Map serviceResult = run service: 'updateShoppingListItem', with: [*: shoppingListItem, - quantity: totalQty] - if (!ServiceUtil.isSuccess(serviceResult)) { - return error(serviceResult.errorMessage) - } - result.shoppingListItemSeqId = shoppingListItem.shoppingListItemSeqId - } else { - GenericValue shoppingList = from('ShoppingList').where(parameters).queryOne() - GenericValue product = from('Product').where(parameters).queryOne() - if (!product) { - return error(UtilProperties.getMessage('ProductUiLabels', 'ProductErrorProductNotFound', parameters.locale)) + for (GenericValue shoppingListItem : shoppingListItems) { + List slItemAttributes = select('attrName', 'attrValue') + .from('ShoppingListItemAttribute') + .where('shoppingListId', parameters.shoppingListId, 'shoppingListItemSeqId', shoppingListItem.shoppingListItemSeqId) + .queryList() + if ((!slItemAttributes && !parameters.shoppingListItemAttributes) || + UtilValidate.areEqual(slItemAttributes, parameters.shoppingListItemAttributes)) { + BigDecimal totalquantity = shoppingListItem.quantity + parameters.quantity + result.shoppingListItemSeqId = shoppingListItem.shoppingListItemSeqId + Map serviceResult = run service: 'updateShoppingListItem', with: [* : shoppingListItem, + quantity: totalquantity] + if (!ServiceUtil.isSuccess(serviceResult)) { + return error(serviceResult.errorMessage) + } + // Exit here, because we found an existing item update, otherwise we have to create a new one below + return result + } } - GenericValue newEntity = makeValue('ShoppingListItem') - newEntity.setNonPKFields(parameters) - newEntity.shoppingListId = parameters.shoppingListId - delegator.setNextSubSeqId(newEntity, 'shoppingListItemSeqId', 5, 1) - newEntity.create() - - result.shoppingListItemSeqId = newEntity.shoppingListItemSeqId - updateLastAdminModified(shoppingList, userLogin) } + // Create new ShoppingListItem + GenericValue shoppingList = from('ShoppingList').where(parameters).queryOne() + GenericValue product = from('Product').where(parameters).queryOne() + if (!product) { + return error(UtilProperties.getMessage('ProductUiLabels', 'ProductErrorProductNotFound', parameters.locale)) + } + GenericValue newEntity = makeValue('ShoppingListItem') + newEntity.setNonPKFields(parameters) + newEntity.shoppingListId = parameters.shoppingListId + delegator.setNextSubSeqId(newEntity, 'shoppingListItemSeqId', 5, 1) + newEntity.create() + + result.shoppingListItemSeqId = newEntity.shoppingListItemSeqId + updateLastAdminModified(shoppingList, userLogin) + return result } diff --git a/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCart.java b/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCart.java index fef531cd16..42f9c702ec 100644 --- a/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCart.java +++ b/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCart.java @@ -652,12 +652,6 @@ public class ShoppingCart implements Iterable<ShoppingCartItem>, Serializable { reserveAfterDate, features, attributes, prodCatalogId, configWrapper, itemType, itemGroup, dispatcher, this, Boolean.TRUE, Boolean.TRUE, parentProductId, Boolean.FALSE, Boolean.FALSE); } - // add order item attributes - if (UtilValidate.isNotEmpty(orderItemAttributes)) { - for (Entry<String, String> entry : orderItemAttributes.entrySet()) { - item.setOrderItemAttribute(entry.getKey(), entry.getValue()); - } - } return this.addItem(0, item); @@ -5013,7 +5007,6 @@ public class ShoppingCart implements Iterable<ShoppingCartItem>, Serializable { } List<GenericValue> supplierProducts = UtilGenerics.cast(getSuppliersForProductResult.get("supplierProducts")); - if (supplierProducts.isEmpty()) { return ServiceUtil.returnError( "Sorry! No supplier available to droship product #" + productId + " with quantity " diff --git a/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartItem.java b/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartItem.java index 3ba990b1a6..8a3064b45d 100644 --- a/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartItem.java +++ b/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartItem.java @@ -31,6 +31,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import org.apache.ofbiz.base.util.Debug; @@ -532,20 +533,44 @@ public class ShoppingCartItem implements java.io.Serializable { parentProductId, skipInventoryChecks, skipProductChecks); } + /** + * Method for backwards compatibility after extending makeItem method below with + * additional orderItemAttributes parameter. + */ + public static ShoppingCartItem makeItem(Integer cartLocation, String productId, BigDecimal selectedAmount, + BigDecimal quantity, BigDecimal unitPrice, + Timestamp reservStart, BigDecimal reservLength, BigDecimal reservPersons, String accommodationMapId, + String accommodationSpotId, Timestamp shipBeforeDate, Timestamp shipAfterDate, Timestamp reserveAfterDate, + Map<String, GenericValue> additionalProductFeatureAndAppls, Map<String, Object> attributes, + String prodCatalogId, ProductConfigWrapper configWrapper, + String itemType, ShoppingCart.ShoppingCartItemGroup itemGroup, LocalDispatcher dispatcher, + ShoppingCart cart, Boolean triggerExternalOpsBool, Boolean triggerPriceRulesBool, String parentProductId, + Boolean skipInventoryChecks, Boolean skipProductChecks) + throws CartItemModifyException, ItemNotFoundException { + + return makeItem(cartLocation, productId, selectedAmount, quantity, unitPrice, + reservStart, reservLength, reservPersons, null, null, shipBeforeDate, shipAfterDate, null, + additionalProductFeatureAndAppls, attributes, null, prodCatalogId, configWrapper, + itemType, itemGroup, dispatcher, cart, triggerExternalOpsBool, triggerPriceRulesBool, + parentProductId, skipInventoryChecks, skipProductChecks); + + } + /** * Makes a ShoppingCartItem and adds it to the cart. - * @param accommodationMapId Optional. reservations add into workeffort + * @param accommodationMapId Optional. reservations add into workeffort * @param accommodationSpotId Optional. reservations add into workeffort - */ - public static ShoppingCartItem makeItem(Integer cartLocation, String productId, BigDecimal selectedAmount, BigDecimal quantity, - BigDecimal unitPrice, - Timestamp reservStart, BigDecimal reservLength, BigDecimal reservPersons, String accommodationMapId, - String accommodationSpotId, Timestamp shipBeforeDate, Timestamp shipAfterDate, Timestamp reserveAfterDate, - Map<String, GenericValue> additionalProductFeatureAndAppls, Map<String, Object> attributes, - String prodCatalogId, ProductConfigWrapper configWrapper, - String itemType, ShoppingCart.ShoppingCartItemGroup itemGroup, LocalDispatcher dispatcher, - ShoppingCart cart, Boolean triggerExternalOpsBool, Boolean triggerPriceRulesBool, String parentProductId, - Boolean skipInventoryChecks, Boolean skipProductChecks) + * @param orderItemAttributes Optional. + */ + public static ShoppingCartItem makeItem(Integer cartLocation, String productId, BigDecimal selectedAmount, + BigDecimal quantity, BigDecimal unitPrice, Timestamp reservStart, BigDecimal reservLength, + BigDecimal reservPersons, String accommodationMapId, String accommodationSpotId, Timestamp shipBeforeDate, + Timestamp shipAfterDate, Timestamp reserveAfterDate, Map<String, + GenericValue> additionalProductFeatureAndAppls, Map<String, Object> attributes, + Map<String, String> orderItemAttributes, String prodCatalogId, ProductConfigWrapper configWrapper, + String itemType, ShoppingCart.ShoppingCartItemGroup itemGroup, LocalDispatcher dispatcher, + ShoppingCart cart, Boolean triggerExternalOpsBool, Boolean triggerPriceRulesBool, String parentProductId, + Boolean skipInventoryChecks, Boolean skipProductChecks) throws CartItemModifyException, ItemNotFoundException { Delegator delegator = cart.getDelegator(); GenericValue product = findProduct(delegator, skipProductChecks, prodCatalogId, productId, cart.getLocale()); @@ -553,16 +578,17 @@ public class ShoppingCartItem implements java.io.Serializable { if (parentProductId != null) { try { - parentProduct = EntityQuery.use(delegator).from("Product").where("productId", parentProductId).cache().queryOne(); + parentProduct = EntityQuery.use(delegator).from("Product").where("productId", parentProductId).cache() + .queryOne(); } catch (GenericEntityException e) { Debug.logWarning(e.toString(), MODULE); } } return makeItem(cartLocation, product, selectedAmount, quantity, unitPrice, - reservStart, reservLength, reservPersons, accommodationMapId, accommodationSpotId, shipBeforeDate, shipAfterDate, reserveAfterDate, - additionalProductFeatureAndAppls, attributes, prodCatalogId, configWrapper, - itemType, itemGroup, dispatcher, cart, triggerExternalOpsBool, triggerPriceRulesBool, parentProduct, skipInventoryChecks, - skipProductChecks); + reservStart, reservLength, reservPersons, accommodationMapId, accommodationSpotId, shipBeforeDate, + shipAfterDate, reserveAfterDate, additionalProductFeatureAndAppls, attributes, orderItemAttributes, + prodCatalogId, configWrapper, itemType, itemGroup, dispatcher, cart, triggerExternalOpsBool, + triggerPriceRulesBool, parentProduct, skipInventoryChecks, skipProductChecks); } /** @@ -610,23 +636,48 @@ public class ShoppingCartItem implements java.io.Serializable { triggerExternalOpsBool, triggerPriceRulesBool, parentProduct, skipInventoryChecks, skipProductChecks); } + /** + * Method for backwards compatibility after extending makeItem method below with + * additional orderItemAttributes parameter. + */ + public static ShoppingCartItem makeItem(Integer cartLocation, GenericValue product, BigDecimal selectedAmount, + BigDecimal quantity, BigDecimal unitPrice, Timestamp reservStart, BigDecimal reservLength, + BigDecimal reservPersons, + String accommodationMapId, String accommodationSpotId, + Timestamp shipBeforeDate, Timestamp shipAfterDate, Timestamp reserveAfterDate, + Map<String, GenericValue> additionalProductFeatureAndAppls, Map<String, Object> attributes, + String prodCatalogId, ProductConfigWrapper configWrapper, String itemType, + ShoppingCart.ShoppingCartItemGroup itemGroup, LocalDispatcher dispatcher, + ShoppingCart cart, Boolean triggerExternalOpsBool, Boolean triggerPriceRulesBool, + GenericValue parentProduct, Boolean skipInventoryChecks, Boolean skipProductChecks) + throws CartItemModifyException { + + return makeItem(cartLocation, product, selectedAmount, + quantity, unitPrice, reservStart, reservLength, reservPersons, + null, null, shipBeforeDate, shipAfterDate, null, additionalProductFeatureAndAppls, attributes, null, + prodCatalogId, configWrapper, itemType, itemGroup, dispatcher, cart, + triggerExternalOpsBool, triggerPriceRulesBool, parentProduct, skipInventoryChecks, skipProductChecks); + } + /** * Makes a ShoppingCartItem and adds it to the cart. - * @param accommodationMapId Optional. reservations add into workeffort + * @param accommodationMapId Optional. reservations add into workeffort * @param accommodationSpotId Optional. reservations add into workeffort + * @param orderItemAttributes Optional. */ public static ShoppingCartItem makeItem(Integer cartLocation, GenericValue product, BigDecimal selectedAmount, - BigDecimal quantity, BigDecimal unitPrice, Timestamp reservStart, BigDecimal reservLength, - BigDecimal reservPersons, String accommodationMapId, String accommodationSpotId, - Timestamp shipBeforeDate, Timestamp shipAfterDate, Timestamp reserveAfterDate, - Map<String, GenericValue> additionalProductFeatureAndAppls, Map<String, Object> attributes, - String prodCatalogId, ProductConfigWrapper configWrapper, String itemType, - ShoppingCart.ShoppingCartItemGroup itemGroup, LocalDispatcher dispatcher, - ShoppingCart cart, Boolean triggerExternalOpsBool, Boolean triggerPriceRulesBool, - GenericValue parentProduct, Boolean skipInventoryChecks, Boolean skipProductChecks) + BigDecimal quantity, BigDecimal unitPrice, Timestamp reservStart, BigDecimal reservLength, + BigDecimal reservPersons, String accommodationMapId, String accommodationSpotId, + Timestamp shipBeforeDate, Timestamp shipAfterDate, Timestamp reserveAfterDate, + Map<String, GenericValue> additionalProductFeatureAndAppls, Map<String, Object> attributes, + Map<String, String> orderItemAttributes, String prodCatalogId, ProductConfigWrapper configWrapper, + String itemType, ShoppingCart.ShoppingCartItemGroup itemGroup, LocalDispatcher dispatcher, + ShoppingCart cart, Boolean triggerExternalOpsBool, Boolean triggerPriceRulesBool, + GenericValue parentProduct, Boolean skipInventoryChecks, Boolean skipProductChecks) throws CartItemModifyException { - ShoppingCartItem newItem = new ShoppingCartItem(product, additionalProductFeatureAndAppls, attributes, prodCatalogId, configWrapper, + ShoppingCartItem newItem = new ShoppingCartItem(product, additionalProductFeatureAndAppls, attributes, + prodCatalogId, configWrapper, cart.getLocale(), itemType, itemGroup, parentProduct); selectedAmount = selectedAmount == null ? BigDecimal.ZERO : selectedAmount; @@ -717,6 +768,12 @@ public class ShoppingCartItem implements java.io.Serializable { // if triggerPriceRules is true this price will be overriden newItem.setBasePrice(unitPrice); + if (UtilValidate.isNotEmpty(orderItemAttributes)) { + for (Entry<String, String> entry : orderItemAttributes.entrySet()) { + newItem.setOrderItemAttribute(entry.getKey(), entry.getValue()); + } + } + // add to cart before setting quantity so that we can get order total, etc if (cartLocation == null) { cart.addItemToEnd(newItem); diff --git a/applications/order/src/main/java/org/apache/ofbiz/order/shoppinglist/ShoppingListEvents.java b/applications/order/src/main/java/org/apache/ofbiz/order/shoppinglist/ShoppingListEvents.java index 08a1112864..dbc98caa17 100644 --- a/applications/order/src/main/java/org/apache/ofbiz/order/shoppinglist/ShoppingListEvents.java +++ b/applications/order/src/main/java/org/apache/ofbiz/order/shoppinglist/ShoppingListEvents.java @@ -152,10 +152,13 @@ public class ShoppingListEvents { Debug.logInfo("Adding cart item to shopping list [" + shoppingListId + "], allowPromo=" + allowPromo + ", item.getIsPromo()=" + item.getIsPromo() + ", item.getProductId()=" + item.getProductId() + ", item.getQuantity()=" + item.getQuantity(), MODULE); + Map<String, String> itemAttributes = item.getOrderItemAttributes(); Map<String, Object> serviceResult = null; try { - Map<String, Object> ctx = UtilMisc.<String, Object>toMap("userLogin", userLogin, "shoppingListId", shoppingListId, + Map<String, Object> ctx = UtilMisc.<String, Object>toMap("userLogin", userLogin, + "shoppingListId", shoppingListId, "productId", item.getProductId(), "quantity", item.getQuantity()); + ctx.put("shoppingListItemAttributes", itemAttributes); ctx.put("reservStart", item.getReservStart()); ctx.put("reservLength", item.getReservLength()); ctx.put("reservPersons", item.getReservPersons()); @@ -173,6 +176,24 @@ public class ShoppingListEvents { errMsg = UtilProperties.getMessage(RES_ERROR, "shoppinglistevents.error_adding_item_to_shopping_list", cart.getLocale()); throw new IllegalArgumentException(errMsg); } + + // store all currenlty existing OrderItemAttributes as ShoppingListItemAttributes + if (UtilValidate.isNotEmpty(itemAttributes)) { + for (Map.Entry<String, String> itemAttrib : itemAttributes.entrySet()) { + try { + GenericValue sliAttrib = delegator.makeValue("ShoppingListItemAttribute", UtilMisc + .toMap("shoppingListId", shoppingListId, + "shoppingListItemSeqId", serviceResult.get("shoppingListItemSeqId"), + "attrName", itemAttrib.getKey(), "attrValue", itemAttrib.getValue())); + delegator.createOrStore(sliAttrib); + } catch (GenericEntityException e) { + Debug.logError(e, "Problems creating ShoppingListItemAttribute entity", MODULE); + errMsg = UtilProperties.getMessage(RES_ERROR, + "shoppinglistevents.error_adding_item_to_shopping_list", cart.getLocale()); + throw new IllegalArgumentException(errMsg); + } + } + } } } } @@ -258,6 +279,9 @@ public class ShoppingListEvents { // get the survey info for all the items Map<String, List<String>> shoppingListSurveyInfo = getItemSurveyInfos(shoppingListItems); + // get the itemAttributeInfos for all the items + Map<String, Map<String, String>> itemAttributeInfos = getItemAttributeInfos(shoppingListItems); + // add the items StringBuilder eventMessage = new StringBuilder(); for (GenericValue shoppingListItem : shoppingListItems) { @@ -292,15 +316,13 @@ public class ShoppingListEvents { } // TODO: add code to check for survey response requirement - // i cannot get the addOrDecrease function to accept a null reservStart field: i get a null pointer exception a null constant works - // .... - if (reservStart == null) { - cart.addOrIncreaseItem(productId, null, quantity, null, null, null, null, null, null, attributes, prodCatalogId, configWrapper, - null, null, null, dispatcher); - } else { - cart.addOrIncreaseItem(productId, null, quantity, reservStart, reservLength, reservPersons, null, null, null, null, null, - attributes, prodCatalogId, configWrapper, null, null, null, dispatcher); - } + // add shoppingListItemAttributes as orderItemAttributes to cart item + Map<String, String> orderItemAttributes = itemAttributeInfos.get(listId + "." + itemId); + + cart.addOrIncreaseItem(productId, null, quantity, reservStart, reservLength, reservPersons, null, null, + null, null, null, attributes, orderItemAttributes, prodCatalogId, configWrapper, null, null, + null, dispatcher); + Map<String, Object> messageMap = UtilMisc.<String, Object>toMap("productId", productId); errMsg = UtilProperties.getMessage(RES_ERROR, "shoppinglistevents.added_product_to_cart", messageMap, cart.getLocale()); eventMessage.append(errMsg).append("\n"); @@ -554,6 +576,7 @@ public class ShoppingListEvents { public static int clearListInfo(Delegator delegator, String shoppingListId) throws GenericEntityException { // remove the survey responses first delegator.removeByAnd("ShoppingListItemSurvey", UtilMisc.toMap("shoppingListId", shoppingListId)); + delegator.removeByAnd("ShoppingListItemAttribute", UtilMisc.toMap("shoppingListId", shoppingListId)); // next remove the items return delegator.removeByAnd("ShoppingListItem", UtilMisc.toMap("shoppingListId", shoppingListId)); @@ -578,6 +601,37 @@ public class ShoppingListEvents { return -1; } + /** + * Returns Map keyed on item sequence ID containing a map of item attributes + */ + public static Map<String, Map<String, String>> getItemAttributeInfos(List<GenericValue> items) { + Map<String, Map<String, String>> attributeInfos = new HashMap<>(); + if (UtilValidate.isNotEmpty(items)) { + for (GenericValue item : items) { + String listId = item.getString("shoppingListId"); + String itemId = item.getString("shoppingListItemSeqId"); + String itemKey = listId + "." + itemId; + + try { + List<GenericValue> itemAttributes = item.getRelated("ShoppingListItemAttribute", null, null, true); + for (GenericValue attribute : itemAttributes) { + Map<String, String> attribMap = attributeInfos.get(itemKey); + if (attribMap == null) { + attribMap = new HashMap<>(); + attributeInfos.put(itemKey, attribMap); + } + attribMap.put(attribute.getString("attrName"), attribute.getString("attrValue")); + } + } catch (GenericEntityException e) { + Debug.logWarning(e, "Error loading related ShoppingListItemAttributes for shoppingListItem " + + item); + } + } + } + + return attributeInfos; + } + /** * Returns Map keyed on item sequence ID containing a list of survey response IDs */ diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index 0c68c12a6a..a1655112b6 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -79,7 +79,7 @@ under the License. <property name="countEmpty" value="false"/> </module> <module name="ParameterNumber"> - <property name="max" value="26"/> + <property name="max" value="27"/> <property name="tokens" value="METHOD_DEF"/> <property name="ignoreOverriddenMethods" value="true"/> </module>