This is an automated email from the ASF dual-hosted git repository. diveshdut pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git
commit 4d0a4a683daa57e5c78f9a068a838acce287c938 Author: diveshdut <[email protected]> AuthorDate: Fri Jul 31 14:24:29 2026 +0530 OFBIZ-13468 Improved: validate and secure BOM association services Add Manufacturing CREATE permission checks to createBOMAssoc and copyBOMAssocs so REST-mapped BOM mutations enforce service-level authorization. Tighten createBOMAssoc validation by rejecting self-referencing BOM associations, checking for an existing ProductAssoc before create, and returning validation failures as service errors. Improve copyBOMAssocs by filtering the source associations with the requested BOM key fields and preserving a supplied fromDate when creating copied associations. --- .../minilang/bom/BomSimpleMethods.xml | 36 ++++++++++++++++++++-- .../manufacturing/servicedef/services_bom.xml | 7 +++-- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/applications/manufacturing/minilang/bom/BomSimpleMethods.xml b/applications/manufacturing/minilang/bom/BomSimpleMethods.xml index c72e310c5d..3fd854f4cc 100644 --- a/applications/manufacturing/minilang/bom/BomSimpleMethods.xml +++ b/applications/manufacturing/minilang/bom/BomSimpleMethods.xml @@ -26,6 +26,25 @@ under the License. <now-timestamp field="parameters.fromDate"/> </if-empty> + <if-compare-field field="parameters.productId" to-field="parameters.productIdTo" operator="equals"> + <property-to-field property="ManufacturingBomProductCannotBeComponentOfItself" resource="ManufacturingUiLabels" field="errorMessage"/> + <add-error> + <fail-message message="${errorMessage}"/> + </add-error> + <check-errors/> + </if-compare-field> + + <make-value entity-name="ProductAssoc" value-field="productAssocLookup"/> + <set-pk-fields map="parameters" value-field="productAssocLookup"/> + <find-by-primary-key entity-name="ProductAssoc" map="productAssocLookup" value-field="existingProductAssoc"/> + <if-not-empty field="existingProductAssoc.productId"> + <set field="errorMessage" value="Value found, cannot create a new one"/> + <add-error> + <fail-message message="${errorMessage}"/> + </add-error> + <check-errors/> + </if-not-empty> + <set field="searchDuplicatedAncestorContext.productId" from-field="parameters.productId"/> <set field="searchDuplicatedAncestorContext.productIdTo" from-field="parameters.productIdTo"/> <if-not-empty field="parameters.fromDate"> @@ -39,8 +58,10 @@ under the License. <set field="productToProduct[]" from-field="duplicatedProductAssoc.productId"/> <set field="productToProduct[]" from-field="duplicatedProductAssoc.productIdTo"/> <property-to-field property="ManufacturingDuplicatedComponentInBOM" resource="ManufacturingUiLabels" field="errorMessage" arg-list-name="productToProduct"/> - <field-to-result field="errorMessage" result-name="errorMessage"/> - <return/> + <add-error> + <fail-message message="${errorMessage}"/> + </add-error> + <check-errors/> </if-not-empty> <set-service-fields service-name="createProductAssoc" map="parameters" to-map="context"/> <call-service service-name="createProductAssoc" in-map-name="context"/> @@ -48,12 +69,21 @@ under the License. <simple-method method-name="copyBOMAssocs" short-description="Copy BOM associations from one product to another"> <make-value entity-name="ProductAssoc" value-field="lookupMap"/> - <set-pk-fields map="parameters" value-field="lookupMap"/> + <set field="lookupMap.productId" from-field="parameters.productId"/> + <if-not-empty field="parameters.productAssocTypeId"> + <set field="lookupMap.productAssocTypeId" from-field="parameters.productAssocTypeId"/> + </if-not-empty> + <if-not-empty field="parameters.productIdTo"> + <set field="lookupMap.productIdTo" from-field="parameters.productIdTo"/> + </if-not-empty> <find-by-and entity-name="ProductAssoc" map="lookupMap" list="assocs"/> <filter-list-by-date list="assocs"/> <iterate list="assocs" entry="assoc"> <set-service-fields service-name="createBOMAssoc" map="assoc" to-map="context"/> <set field="context.productId" from-field="parameters.copyToProductId"/> + <if-not-empty field="parameters.fromDate"> + <set field="context.fromDate" from-field="parameters.fromDate"/> + </if-not-empty> <call-service service-name="createBOMAssoc" in-map-name="context" break-on-error="false"/> </iterate> </simple-method> diff --git a/applications/manufacturing/servicedef/services_bom.xml b/applications/manufacturing/servicedef/services_bom.xml index b46afa4fa8..a7a78299ed 100644 --- a/applications/manufacturing/servicedef/services_bom.xml +++ b/applications/manufacturing/servicedef/services_bom.xml @@ -27,15 +27,16 @@ under the License. <!-- Bill of Materials services --> <service name="createBOMAssoc" default-entity-name="ProductAssoc" engine="simple" location="component://manufacturing/minilang/bom/BomSimpleMethods.xml" invoke="createBOMAssoc" auth="true"> - <description>Add Product to Product Association</description> + <description>Add a product to a BOM as a ProductAssoc component. Validates that a product is not added as its own component, rejects duplicate associations before create, and delegates the actual ProductAssoc create to the existing product association service.</description> + <permission-service service-name="manufacturingPermissionService" main-action="CREATE"/> <auto-attributes include="pk" mode="IN" optional="false"/> <auto-attributes include="nonpk" mode="IN" optional="true"/> - <attribute name="errorMessage" type="String" optional="true" mode="OUT"/> <override name="fromDate" optional="true"/> </service> <service name="copyBOMAssocs" default-entity-name="ProductAssoc" engine="simple" location="component://manufacturing/minilang/bom/BomSimpleMethods.xml" invoke="copyBOMAssocs" auth="true"> - <description>Copy BOM associations from one product to another</description> + <description>Copy active BOM associations from one product to another. Reuses BOM association creation for each copied component, supports narrowing the source associations by BOM key fields, and preserves a supplied effective fromDate for REST/API copy workflows.</description> + <permission-service service-name="manufacturingPermissionService" main-action="CREATE"/> <auto-attributes include="pk" mode="IN" optional="false"/> <attribute name="copyToProductId" type="String" optional="false" mode="IN"/> <override name="fromDate" optional="true"/>

