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 b8c490b8d9ca29ad5dfc72bcaf83ea9a257f6473 Author: diveshdut <[email protected]> AuthorDate: Tue Aug 4 16:55:09 2026 +0530 OFBIZ-13480 Add manufacturing lookup services for routing management Add reusable manufacturing lookup services for product search, party search, fixed asset selection, and cost component setup options. These services give REST clients stable paged lookup payloads while keeping the lookup contracts separate from routing-specific service definitions. Existing BOM lookup services remain unchanged; searchProducts delegates to the existing product lookup shape, and findProductLookupOptions/findWarehouses continue to be defined for the BOM API as before. --- applications/manufacturing/ofbiz-component.xml | 1 + .../manufacturing/servicedef/services_lookup.xml | 72 ++++++++++++ .../api/ManufacturingLookupServices.groovy | 122 +++++++++++++++++++++ .../api/ManufacturingServiceUtil.groovy | 4 + 4 files changed, 199 insertions(+) diff --git a/applications/manufacturing/ofbiz-component.xml b/applications/manufacturing/ofbiz-component.xml index 071f38c02a..0ab6509e9d 100644 --- a/applications/manufacturing/ofbiz-component.xml +++ b/applications/manufacturing/ofbiz-component.xml @@ -34,6 +34,7 @@ under the License. <!-- service resources: model(s) [definitions], eca(s) and group definitions --> <service-resource type="model" loader="main" location="servicedef/services.xml"/> + <service-resource type="model" loader="main" location="servicedef/services_lookup.xml"/> <service-resource type="model" loader="main" location="servicedef/services_calendar.xml"/> <service-resource type="model" loader="main" location="servicedef/services_routing.xml"/> <service-resource type="model" loader="main" location="servicedef/services_production_run.xml"/> diff --git a/applications/manufacturing/servicedef/services_lookup.xml b/applications/manufacturing/servicedef/services_lookup.xml new file mode 100644 index 0000000000..13b8e493ce --- /dev/null +++ b/applications/manufacturing/servicedef/services_lookup.xml @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> + +<services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="https://ofbiz.apache.org/dtds/services.xsd"> + <description>Manufacturing Lookup Services</description> + + <service name="findCostComponentOptions" engine="groovy" auth="true" + location="component://manufacturing/src/main/groovy/org/apache/ofbiz/manufacturing/api/ManufacturingLookupServices.groovy" invoke="findCostComponentOptions"> + <description>Find cost component types and calculation records used by manufacturing setup screens, so REST clients can populate cost-rate selectors without issuing separate generic entity queries.</description> + <attribute mode="OUT" name="costComponentTypes" optional="false" type="java.util.List"/> + <attribute mode="OUT" name="costComponentCalcs" optional="false" type="java.util.List"/> + </service> + <service name="findFixedAssets" engine="groovy" auth="true" + location="component://manufacturing/src/main/groovy/org/apache/ofbiz/manufacturing/api/ManufacturingLookupServices.groovy" invoke="findFixedAssets"> + <description>Find fixed assets available to manufacturing workflows, with REST paging and sorting, so routing and other manufacturing applications can select equipment or tool references from a stable lookup payload.</description> + <attribute mode="IN" name="fixedAssetTypeId" optional="true" type="String"/> + <attribute mode="IN" name="pageIndex" optional="true" type="Integer"/> + <attribute mode="IN" name="pageSize" optional="true" type="Integer"/> + <attribute mode="IN" name="sort" optional="true" type="String"/> + <attribute mode="OUT" name="pageIndex" optional="false" type="Integer"/> + <attribute mode="OUT" name="pageSize" optional="false" type="Integer"/> + <attribute mode="OUT" name="totalCount" optional="false" type="Long"/> + <attribute mode="OUT" name="totalPages" optional="false" type="Long"/> + <attribute mode="OUT" name="hasNext" optional="false" type="Boolean"/> + <attribute mode="OUT" name="fixedAssets" optional="false" type="java.util.List"/> + </service> + <service name="searchProducts" engine="groovy" auth="true" + location="component://manufacturing/src/main/groovy/org/apache/ofbiz/manufacturing/api/ManufacturingLookupServices.groovy" invoke="searchProducts"> + <description>Search products by ID, product name, or internal name using the shared manufacturing product lookup shape, so REST clients can reuse one product picker contract across BOM, routing, and related manufacturing flows.</description> + <attribute mode="IN" name="query" optional="true" type="String"/> + <attribute mode="IN" name="pageIndex" optional="true" type="Integer"/> + <attribute mode="IN" name="pageSize" optional="true" type="Integer"/> + <attribute mode="OUT" name="pageIndex" optional="false" type="Integer"/> + <attribute mode="OUT" name="pageSize" optional="false" type="Integer"/> + <attribute mode="OUT" name="totalCount" optional="false" type="Long"/> + <attribute mode="OUT" name="totalPages" optional="false" type="Long"/> + <attribute mode="OUT" name="hasNext" optional="false" type="Boolean"/> + <attribute mode="OUT" name="products" optional="false" type="java.util.List"/> + </service> + <service name="searchParties" engine="groovy" auth="true" + location="component://manufacturing/src/main/groovy/org/apache/ofbiz/manufacturing/api/ManufacturingLookupServices.groovy" invoke="searchParties"> + <description>Search parties by ID or display name with REST paging and sorting, so manufacturing applications can assign people or groups to operations without depending on UI-specific party lookup screens.</description> + <attribute mode="IN" name="query" optional="true" type="String"/> + <attribute mode="IN" name="pageIndex" optional="true" type="Integer"/> + <attribute mode="IN" name="pageSize" optional="true" type="Integer"/> + <attribute mode="IN" name="sort" optional="true" type="String"/> + <attribute mode="OUT" name="pageIndex" optional="false" type="Integer"/> + <attribute mode="OUT" name="pageSize" optional="false" type="Integer"/> + <attribute mode="OUT" name="totalCount" optional="false" type="Long"/> + <attribute mode="OUT" name="totalPages" optional="false" type="Long"/> + <attribute mode="OUT" name="hasNext" optional="false" type="Boolean"/> + <attribute mode="OUT" name="parties" optional="false" type="java.util.List"/> + </service> +</services> diff --git a/applications/manufacturing/src/main/groovy/org/apache/ofbiz/manufacturing/api/ManufacturingLookupServices.groovy b/applications/manufacturing/src/main/groovy/org/apache/ofbiz/manufacturing/api/ManufacturingLookupServices.groovy index 19ae356b8c..50750d5a5c 100644 --- a/applications/manufacturing/src/main/groovy/org/apache/ofbiz/manufacturing/api/ManufacturingLookupServices.groovy +++ b/applications/manufacturing/src/main/groovy/org/apache/ofbiz/manufacturing/api/ManufacturingLookupServices.groovy @@ -24,6 +24,7 @@ import org.apache.ofbiz.entity.condition.EntityCondition import org.apache.ofbiz.entity.condition.EntityOperator import org.apache.ofbiz.entity.util.EntityQuery import org.apache.ofbiz.entity.util.EntityUtil +import org.apache.ofbiz.party.party.PartyHelper import org.apache.ofbiz.service.ServiceUtil import org.apache.ofbiz.ws.rs.util.RestApiUtil import org.apache.ofbiz.ws.rs.util.RestQueryOptions @@ -61,6 +62,127 @@ Map findProductLookupOptions() { return success(RestApiUtil.getPagedResult('products', products, queryOptions, totalCount, null)) } +Map searchProducts() { + return findProductLookupOptions() +} + +Map searchParties() { + RestQueryOptions queryOptions + try { + queryOptions = RestQueryOptions.fromParameters(parameters) + } catch (IllegalArgumentException e) { + return ServiceUtil.returnError(e.message) + } + Map filters = queryOptions.filters + List orderBy + try { + orderBy = RestApiUtil.resolveOrderBy(queryOptions.sort, [ + partyId: 'partyId', + partyName: 'groupName', + groupName: 'groupName', + firstName: 'firstName', + lastName: 'lastName' + ], ['partyId']) + } catch (IllegalArgumentException e) { + return ServiceUtil.returnError(e.message) + } + String queryText = filters.query?.trim() + if (UtilValidate.isEmpty(queryText)) { + return success(RestApiUtil.getPagedResult('parties', [], queryOptions, 0L, null)) + } + + EntityCondition searchCondition = EntityUtil.upperLikeAny(['partyId', 'firstName', 'lastName', 'groupName'], queryText) + EntityQuery partyQuery = from('PartyNameView') + .select('partyId', 'partyTypeId', 'firstName', 'middleName', 'lastName', 'groupName') + .where(searchCondition) + long totalCount = partyQuery.queryCount() + List partyRows = partyQuery.orderBy(orderBy) + .queryPagedList(queryOptions.pageIndex, queryOptions.pageSize).getData() + List parties = partyRows.collect { GenericValue party -> + String partyName = PartyHelper.getPartyName(party, false) ?: party.partyId + [ + partyId: party.partyId, + partyTypeId: party.partyTypeId, + partyName: partyName, + label: partyName + ] + } + return success(RestApiUtil.getPagedResult('parties', parties, queryOptions, totalCount, null)) +} + +Map findFixedAssets() { + RestQueryOptions queryOptions + try { + queryOptions = RestQueryOptions.fromParameters(parameters) + } catch (IllegalArgumentException e) { + return ServiceUtil.returnError(e.message) + } + Map filters = queryOptions.filters + List orderBy + try { + orderBy = RestApiUtil.resolveOrderBy(queryOptions.sort, [ + fixedAssetId: 'fixedAssetId', + fixedAssetName: 'fixedAssetName', + fixedAssetTypeId: 'fixedAssetTypeId' + ], ['fixedAssetName', 'fixedAssetId']) + } catch (IllegalArgumentException e) { + return ServiceUtil.returnError(e.message) + } + List conditions = [] + if (UtilValidate.isNotEmpty(filters.fixedAssetTypeId)) { + conditions.add(EntityCondition.makeCondition('fixedAssetTypeId', filters.fixedAssetTypeId)) + } + EntityQuery query = from('FixedAsset') + .select('fixedAssetId', 'fixedAssetName', 'fixedAssetTypeId') + if (conditions) { + query.where(EntityCondition.makeCondition(conditions, EntityOperator.AND)) + } + long totalCount = query.queryCount() + List fixedAssets = query.orderBy(orderBy) + .queryPagedList(queryOptions.pageIndex, queryOptions.pageSize).getData() + .collect { GenericValue fixedAsset -> + String fixedAssetName = ManufacturingServiceUtil.displayFixedAssetName(fixedAsset) + [ + fixedAssetId: fixedAsset.fixedAssetId, + fixedAssetName: fixedAssetName, + fixedAssetTypeId: fixedAsset.fixedAssetTypeId, + label: fixedAssetName + ] + } + return success(RestApiUtil.getPagedResult('fixedAssets', fixedAssets, queryOptions, totalCount, null)) +} + +Map findCostComponentOptions() { + List costComponentTypes = from('CostComponentType') + .select('costComponentTypeId', 'description') + .orderBy('description', 'costComponentTypeId') + .cache(true) + .queryList() + .collect { GenericValue type -> + [ + costComponentTypeId: type.costComponentTypeId, + description: type.description, + label: type.description ?: type.costComponentTypeId + ] + } + List costComponentCalcs = from('CostComponentCalc') + .select('costComponentCalcId', 'description', 'costCustomMethodId', 'fixedCost', 'variableCost', 'currencyUomId') + .orderBy('description', 'costComponentCalcId') + .queryList() + .collect { GenericValue calc -> + [ + costComponentCalcId: calc.costComponentCalcId, + description: calc.description, + costCustomMethodId: calc.costCustomMethodId, + fixedCost: calc.fixedCost, + variableCost: calc.variableCost, + currencyUomId: calc.currencyUomId, + label: calc.description ?: calc.costComponentCalcId + ] + } + return success(costComponentTypes: costComponentTypes, costComponentCalcs: costComponentCalcs) +} + Map findWarehouses() { return findFacilitiesByTypes(['WAREHOUSE', 'PLANT']) } diff --git a/applications/manufacturing/src/main/groovy/org/apache/ofbiz/manufacturing/api/ManufacturingServiceUtil.groovy b/applications/manufacturing/src/main/groovy/org/apache/ofbiz/manufacturing/api/ManufacturingServiceUtil.groovy index c1778e3e55..e807272a77 100644 --- a/applications/manufacturing/src/main/groovy/org/apache/ofbiz/manufacturing/api/ManufacturingServiceUtil.groovy +++ b/applications/manufacturing/src/main/groovy/org/apache/ofbiz/manufacturing/api/ManufacturingServiceUtil.groovy @@ -28,4 +28,8 @@ final class ManufacturingServiceUtil { return product?.productName ?: product?.internalName ?: product?.productId } + static String displayFixedAssetName(GenericValue fixedAsset) { + return fixedAsset?.fixedAssetName ?: fixedAsset?.fixedAssetId + } + }

