[ofbiz-framework] branch trunk updated: Improved: Make shipment services loosely coupled with work-effort generation. (#132)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[ofbiz-framework] branch trunk updated: Improved: Make shipment services loosely coupled with work-effort generation. (#132)

surajk
This is an automated email from the ASF dual-hosted git repository.

surajk 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 8bdb6c9  Improved: Make shipment services loosely coupled with work-effort generation. (#132)
8bdb6c9 is described below

commit 8bdb6c99856fd4ae17a95ccb0f661a256caaab13
Author: Suraj Khurana <[hidden email]>
AuthorDate: Sat May 23 15:26:26 2020 +0530

    Improved: Make shipment services loosely coupled with work-effort generation. (#132)
   
    * Improved: Make shipment services loosely coupled with work-effort generation.
    (OFBIZ-11678)
    Removed workeffort generation related code in separate service, in createShipment and updateShipment service. In this effort, createShipment has been successfully changed to entity-auto as well.
    Thanks: Pierre Smits and Arun Patidar for discussion and review.
---
 .../shipment/shipment/ShipmentServices.groovy      | 156 +-------------------
 applications/product/servicedef/secas_shipment.xml |  16 ++-
 .../product/servicedef/services_shipment.xml       |   7 +-
 .../workeffort/WorkEffortServices.groovy           | 158 +++++++++++++++++++++
 applications/workeffort/servicedef/services.xml    |  12 ++
 .../workeffort/workeffort/WorkEffortServices.java  |   2 +-
 6 files changed, 191 insertions(+), 160 deletions(-)

diff --git a/applications/product/groovyScripts/shipment/shipment/ShipmentServices.groovy b/applications/product/groovyScripts/shipment/shipment/ShipmentServices.groovy
index 026e7a0..1940f59 100644
--- a/applications/product/groovyScripts/shipment/shipment/ShipmentServices.groovy
+++ b/applications/product/groovyScripts/shipment/shipment/ShipmentServices.groovy
@@ -17,8 +17,6 @@
  * under the License.
  */
 
-
-
 import java.sql.Timestamp
 
 import org.apache.ofbiz.base.util.UtilDateTime
@@ -30,83 +28,6 @@ import org.apache.ofbiz.party.contact.ContactMechWorker
 import org.apache.ofbiz.product.product.ProductWorker
 import org.apache.ofbiz.service.ServiceUtil
 
-
-/**
- * Create Shipment
- * @return
- */
-def createShipment() {
-    GenericValue newEntity = makeValue("Shipment")
-    newEntity.setNonPKFields(parameters)
-
-    if (parameters.shipmentId) {
-        newEntity.setPKFields(parameters)
-    } else {
-        newEntity.shipmentId = delegator.getNextSeqId("Shipment")
-    }
-    Map result = success()
-    result.shipmentId = newEntity.shipmentId
-    String shipmentTypeId = parameters.shipmentTypeId
-    // set the created and lastModified info
-    newEntity.createdDate = UtilDateTime.nowTimestamp()
-    newEntity.createdByUserLogin = userLogin.userLoginId
-    newEntity.lastModifiedDate = UtilDateTime.nowTimestamp()
-    newEntity.lastModifiedByUserLogin = userLogin.userLoginId
-    /*
-     * if needed create some WorkEfforts and remember their IDs:
-     * estimatedShipDate: estimatedShipWorkEffId
-     * estimatedArrivalDate: estimatedArrivalWorkEffId
-     */
-    if (parameters.estimatedShipDate) {
-        Map shipWorkEffortMap = [workEffortName: "Shipment #${newEntity.shipmentId} ${newEntity.primaryOrderId} Ship",
-                                 currentStatusId: "CAL_TENTATIVE",
-                                 workEffortPurposeTypeId: "WEPT_WAREHOUSING",
-                                 estimatedStartDate: parameters.estimatedShipDate,
-                                 estimatedCompletionDate: parameters.estimatedShipDate,
-                                 facilityId: parameters.originFacilityId,
-                                 quickAssignPartyId: userLogin.partyId]
-        if (["OUTGOING_SHIPMENT", "SALES_SHIPMENT", "PURCHASE_RETURN"].contains(shipmentTypeId)) {
-            shipWorkEffortMap.workEffortTypeId = "SHIPMENT_OUTBOUND"
-        }
-        Map serviceResultSD = run service: "createWorkEffort", with: shipWorkEffortMap
-        newEntity.estimatedShipWorkEffId = serviceResultSD.workEffortId
-        if (newEntity.partyIdFrom) {
-            run service: "assignPartyToWorkEffort", with: [workEffortId: newEntity.estimatedShipWorkEffId,
-                                                           partyId: newEntity.partyIdFrom,
-                                                           roleTypeId: "CAL_ATTENDEE",
-                                                           statusId: "CAL_SENT"]
-        }
-    }
-    if (parameters.estimatedArrivalDate) {
-        Map arrivalWorkEffortMap = [workEffortName: "Shipment #${newEntity.shipmentId} ${newEntity.primaryOrderId} Arrival",
-                                    currentStatusId: "CAL_TENTATIVE",
-                                    workEffortPurposeTypeId: "WEPT_WAREHOUSING",
-                                    estimatedStartDate: parameters.estimatedArrivalDate,
-                                    estimatedCompletionDate: parameters.estimatedArrivalDate,
-                                    facilityId: parameters.destinationFacilityId,
-                                    quickAssignPartyId: userLogin.partyId]
-        if (["INCOMING_SHIPMENT", "PURCHASE_SHIPMENT", "SALES_RETURN"].contains(shipmentTypeId)) {
-            arrivalWorkEffortMap.workEffortTypeId = "SHIPMENT_INBOUND"
-        }
-        Map serviceResultAD = run service: "createWorkEffort", with: arrivalWorkEffortMap
-        newEntity.estimatedArrivalWorkEffId = serviceResultAD.workEffortId
-        if (newEntity.partyIdTo) {
-            run service: "assignPartyToWorkEffort", with: [workEffortId: newEntity.estimatedArrivalWorkEffId,
-                                                           partyId: newEntity.partyIdTo,
-                                                           roleTypeId: "CAL_ATTENDEE",
-                                                           statusId: "CAL_SENT"]
-        }
-    }
-    newEntity.create()
-
-    // get the ShipmentStatus history started
-    if (newEntity.statusId) {
-        run service: "createShipmentStatus", with: [shipmentId: newEntity.shipmentId,
-                                                    statusId: newEntity.statusId]
-    }
-    return result
-}
-
 /**
  * Update Shipment
  * @return
@@ -140,80 +61,11 @@ def updateShipment() {
     }
     // now finally check for errors
     if (errorList) {
-        return error(errorList)
-    }
-    // Check the pickup and delivery dates for changes and update the corresponding WorkEfforts
-    if ((parameters.estimatedShipDate && parameters.estimatedShipDate != lookedUpValue.estimatedShipDate)
-            || (parameters.originFacilityId && parameters.originFacilityId != lookedUpValue.originFacilityId)
-            || (parameters.statusId && parameters.statusId != lookedUpValue.statusId
-                && ["SHIPMENT_CANCELLED", "SHIPMENT_PACKED", "SHIPMENT_SHIPPED"].contains(parameters.statusId))) {
-        GenericValue estShipWe = from("WorkEffort").where(workEffortId: lookedUpValue.estimatedShipWorkEffId).queryOne()
-        if (estShipWe) {
-            estShipWe.estimatedStartDate = parameters.estimatedShipDate
-            estShipWe.estimatedCompletionDate = parameters.estimatedShipDate
-            estShipWe.facilityId = parameters.originFacilityId
-            if ((parameters.statusId) && (parameters.statusId != lookedUpValue.statusId)) {
-                if (parameters.statusId == "SHIPMENT_CANCELLED") {
-                    estShipWe.currentStatusId = "CAL_CANCELLED"
-                }
-                if (parameters.statusId == "SHIPMENT_PACKED") {
-                    estShipWe.currentStatusId = "CAL_CONFIRMED"
-                }
-                if (parameters.statusId == "SHIPMENT_SHIPPED") {
-                    estShipWe.currentStatusId = "CAL_COMPLETED"
-                }
-            }
-            Map estShipWeUpdMap = [:]
-            estShipWeUpdMap << estShipWe
-            run service: "updateWorkEffort", with: estShipWeUpdMap
-        }
-    }
-    if ((parameters.estimatedArrivalDate
-            && parameters.estimatedArrivalDate != lookedUpValue.estimatedArrivalDate)
-            || (parameters.destinationFacilityId
-            && parameters.destinationFacilityId != lookedUpValue.destinationFacilityId)) {
-        GenericValue estimatedArrivalWorkEffort = from("WorkEffort")
-                .where(workEffortId: lookedUpValue.estimatedArrivalWorkEffId)
-                .queryOne()
-        if (estimatedArrivalWorkEffort) {
-            estimatedArrivalWorkEffort.estimatedStartDate = parameters.estimatedArrivalDate
-            estimatedArrivalWorkEffort.estimatedCompletionDate = parameters.estimatedArrivalDate
-            estimatedArrivalWorkEffort.facilityId = parameters.destinationFacilityId
-            run service: "updateWorkEffort", with: estimatedArrivalWorkEffort
-        }
-    }
-    // if the partyIdTo or partyIdFrom has changed, add WEPAs
-    //TODO REFACTORING
-    if (parameters.partyIdFrom
-            && parameters.partyIdFrom != lookedUpValue.partyIdFrom
-            && lookedUpValue.estimatedShipWorkEffId) {
-        Map assignPartyToWorkEffortShip = [workEffortId: lookedUpValue.estimatedShipWorkEffId,
-                                           partyId: parameters.partyIdFrom]
-        List existingShipWepas = from("WorkEffortPartyAssignment")
-                .where(assignPartyToWorkEffortShip)
-                .filterByDate()
-                .queryList()
-        if (!existingShipWepas) {
-            assignPartyToWorkEffortShip.roleTypeId = "CAL_ATTENDEE"
-            assignPartyToWorkEffortShip.statusId = "CAL_SENT"
-            run service: "assignPartyToWorkEffort", with: assignPartyToWorkEffortShip
-        }
-    }
-    if (parameters.partyIdTo
-            && parameters.partyIdTo != lookedUpValue.partyIdTo
-            && lookedUpValue.estimatedArrivalWorkEffId) {
-        Map assignPartyToWorkEffortArrival = [workEffortId: lookedUpValue.estimatedArrivalWorkEffId,
-                                              partyId: parameters.partyIdTo]
-        List existingArrivalWepas = from("WorkEffortPartyAssignment")
-                .where(assignPartyToWorkEffortArrival)
-                .filterByDate()
-                .queryList()
-        if (!existingArrivalWepas) {
-            assignPartyToWorkEffortArrival.roleTypeId = "CAL_ATTENDEE"
-            assignPartyToWorkEffortArrival.statusId = "CAL_SENT"
-            run service: "assignPartyToWorkEffort", with: assignPartyToWorkEffortArrival
-        }
+        return error(errorList.toString())
     }
+    Map serviceResult = run service: "checkAndUpdateWorkEffort", with: parameters
+    if (!ServiceUtil.isSuccess(serviceResult)) return error(serviceResult.errorMessage)
+
     // finally before setting nonpk fields, set the oldStatusId, oldPrimaryOrderId, oldOriginFacilityId, oldDestinationFacilityId
     result.oldStatusId = lookedUpValue.statusId
     result.oldPrimaryOrderId = lookedUpValue.primaryOrderId
diff --git a/applications/product/servicedef/secas_shipment.xml b/applications/product/servicedef/secas_shipment.xml
index b71fbb9..94f8e2d 100644
--- a/applications/product/servicedef/secas_shipment.xml
+++ b/applications/product/servicedef/secas_shipment.xml
@@ -123,18 +123,30 @@ under the License.
         <condition field-name="destinationFacilityId" operator="is-not-empty"/>
         <action service="setShipmentSettingsFromFacilities" mode="sync"/>
     </eca>
-
     <!-- if new primaryOrderId, get settings from order -->
     <eca service="createShipment" event="commit">
         <condition field-name="primaryOrderId" operator="is-not-empty"/>
         <action service="setShipmentSettingsFromPrimaryOrder" mode="sync"/>
     </eca>
-
     <eca service="updateShipment" event="commit">
         <condition-field field-name="primaryOrderId" operator="not-equals" to-field-name="oldPrimaryOrderId"/>
         <condition field-name="primaryOrderId" operator="is-not-empty"/>
         <action service="setShipmentSettingsFromPrimaryOrder" mode="sync"/>
     </eca>
+    <!-- if estimatedShipDate, create work-effort -->
+    <eca service="createShipment" event="commit">
+        <condition field-name="estimatedShipDate" operator="is-not-empty"/>
+        <action service="checkAndCreateWorkEffort" mode="async"/>
+    </eca>
+    <eca service="createShipment" event="commit">
+        <condition field-name="estimatedArrivalDate" operator="is-not-empty"/>
+        <action service="checkAndCreateWorkEffort" mode="async"/>
+    </eca>
+    <eca service="createShipment" event="commit">
+        <condition field-name="statusId" operator="is-not-empty"/>
+        <action service="createShipmentStatus" mode="async"/>
+    </eca>
+
 
     <eca service="createShipmentReceipt" event="commit">
         <condition field-name="returnId" operator="is-not-empty"/>
diff --git a/applications/product/servicedef/services_shipment.xml b/applications/product/servicedef/services_shipment.xml
index 84aabb0..799b377 100644
--- a/applications/product/servicedef/services_shipment.xml
+++ b/applications/product/servicedef/services_shipment.xml
@@ -163,13 +163,10 @@ under the License.
         </attribute>
         <override name="primaryReturnId" optional="false"/>
     </service>
-
-    <service name="createShipment" default-entity-name="Shipment" engine="groovy"
-            location="component://product/groovyScripts/shipment/shipment/ShipmentServices.groovy" invoke="createShipment" auth="true">
+    <service name="createShipment" default-entity-name="Shipment" engine="entity-auto" invoke="create" auth="true">
         <description>Create Shipment</description>
         <permission-service service-name="facilityGenericPermission" main-action="CREATE"/>
-        <auto-attributes include="pk" mode="OUT" optional="false"/>
-        <auto-attributes include="pk" mode="IN" optional="true"/>
+        <auto-attributes include="pk" mode="INOUT" optional="true"/>
         <auto-attributes include="nonpk" mode="IN" optional="true">
             <exclude field-name="createdDate"/>
             <exclude field-name="createdByUserLogin"/>
diff --git a/applications/workeffort/groovyScripts/workeffort/workeffort/WorkEffortServices.groovy b/applications/workeffort/groovyScripts/workeffort/workeffort/WorkEffortServices.groovy
new file mode 100644
index 0000000..fd0cba7
--- /dev/null
+++ b/applications/workeffort/groovyScripts/workeffort/workeffort/WorkEffortServices.groovy
@@ -0,0 +1,158 @@
+/*
+ * 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.
+ */
+import org.apache.ofbiz.entity.GenericValue
+import org.apache.ofbiz.service.ServiceUtil;
+
+def checkAndCreateWorkEffort() {
+    Map result = success()
+    /*
+     * if needed create some WorkEfforts and remember their IDs:
+     * estimatedShipDate: estimatedShipWorkEffId
+     * estimatedArrivalDate: estimatedArrivalWorkEffId
+     */
+    GenericValue lookedUpValue = from("Shipment").where(parameters).queryOne()
+    if (parameters.estimatedShipDate) {
+        Map shipWorkEffortMap = [workEffortName: "Shipment #${parameters.shipmentId} ${parameters.primaryOrderId} Ship",
+                                 currentStatusId: "CAL_TENTATIVE",
+                                 workEffortPurposeTypeId: "WEPT_WAREHOUSING",
+                                 estimatedStartDate: parameters.estimatedShipDate,
+                                 estimatedCompletionDate: parameters.estimatedShipDate,
+                                 facilityId: parameters.originFacilityId,
+                                 quickAssignPartyId: userLogin.partyId]
+        if (["OUTGOING_SHIPMENT", "SALES_SHIPMENT", "PURCHASE_RETURN"].contains(shipmentTypeId)) {
+            shipWorkEffortMap.workEffortTypeId = "SHIPMENT_OUTBOUND"
+        }
+        Map serviceResult = run service: "createWorkEffort", with: shipWorkEffortMap
+        if (!ServiceUtil.isSuccess(serviceResult)) return error(serviceResult.errorMessage)
+        lookedUpValue.estimatedShipWorkEffId = serviceResult.workEffortId
+        if (parameters.partyIdFrom) {
+            serviceResult = run service: "assignPartyToWorkEffort", with: [workEffortId: lookedUpValue.estimatedShipWorkEffId,
+                                                           partyId: parameters.partyIdFrom,
+                                                           roleTypeId: "CAL_ATTENDEE",
+                                                           statusId: "CAL_SENT"]
+            if (!ServiceUtil.isSuccess(serviceResult)) return error(serviceResult.errorMessage)
+        }
+    }
+    if (parameters.estimatedArrivalDate) {
+        Map arrivalWorkEffortMap = [workEffortName: "Shipment #${parameters.shipmentId} ${parameters.primaryOrderId} Arrival",
+                                    currentStatusId: "CAL_TENTATIVE",
+                                    workEffortPurposeTypeId: "WEPT_WAREHOUSING",
+                                    estimatedStartDate: parameters.estimatedArrivalDate,
+                                    estimatedCompletionDate: parameters.estimatedArrivalDate,
+                                    facilityId: parameters.destinationFacilityId,
+                                    quickAssignPartyId: userLogin.partyId]
+        if (["INCOMING_SHIPMENT", "PURCHASE_SHIPMENT", "SALES_RETURN"].contains(shipmentTypeId)) {
+            arrivalWorkEffortMap.workEffortTypeId = "SHIPMENT_INBOUND"
+        }
+        Map serviceResult = run service: "createWorkEffort", with: arrivalWorkEffortMap
+        if (!ServiceUtil.isSuccess(serviceResult)) return error(serviceResult.errorMessage)
+        lookedUpValue.estimatedArrivalWorkEffId = serviceResultAD.workEffortId
+        if (parameters.partyIdTo) {
+            serviceResult = run service: "assignPartyToWorkEffort", with: [workEffortId: lookedUpValue.estimatedArrivalWorkEffId,
+                                                           partyId: parameters.partyIdTo,
+                                                           roleTypeId: "CAL_ATTENDEE",
+                                                           statusId: "CAL_SENT"]
+            if (!ServiceUtil.isSuccess(serviceResult)) return error(serviceResult.errorMessage)
+        }
+    }
+    lookedUpValue.store()
+    return result
+}
+def checkAndUpdateWorkEffort() {
+    Map result = success()
+    GenericValue lookedUpValue = from("Shipment").where(parameters).queryOne()
+    // Check the pickup and delivery dates for changes and update the corresponding WorkEfforts
+    if ((parameters.estimatedShipDate && parameters.estimatedShipDate != lookedUpValue.estimatedShipDate)
+            || (parameters.originFacilityId && parameters.originFacilityId != lookedUpValue.originFacilityId)
+            || (parameters.statusId && parameters.statusId != lookedUpValue.statusId
+            && ["SHIPMENT_CANCELLED", "SHIPMENT_PACKED", "SHIPMENT_SHIPPED"].contains(parameters.statusId))) {
+        GenericValue estShipWe = from("WorkEffort").where(workEffortId: lookedUpValue.estimatedShipWorkEffId).queryOne()
+        if (estShipWe) {
+            estShipWe.estimatedStartDate = parameters.estimatedShipDate
+            estShipWe.estimatedCompletionDate = parameters.estimatedShipDate
+            estShipWe.facilityId = parameters.originFacilityId
+            if ((parameters.statusId) && (parameters.statusId != lookedUpValue.statusId)) {
+                if (parameters.statusId == "SHIPMENT_CANCELLED") {
+                    estShipWe.currentStatusId = "CAL_CANCELLED"
+                }
+                if (parameters.statusId == "SHIPMENT_PACKED") {
+                    estShipWe.currentStatusId = "CAL_CONFIRMED"
+                }
+                if (parameters.statusId == "SHIPMENT_SHIPPED") {
+                    estShipWe.currentStatusId = "CAL_COMPLETED"
+                }
+            }
+            Map estShipWeUpdMap = [:]
+            estShipWeUpdMap << estShipWe
+            Map serviceResult = run service: "updateWorkEffort", with: estShipWeUpdMap
+            if (!ServiceUtil.isSuccess(serviceResult)) return error(serviceResult.errorMessage)
+
+        }
+    }
+    if ((parameters.estimatedArrivalDate
+            && parameters.estimatedArrivalDate != lookedUpValue.estimatedArrivalDate)
+            || (parameters.destinationFacilityId
+            && parameters.destinationFacilityId != lookedUpValue.destinationFacilityId)) {
+        GenericValue estimatedArrivalWorkEffort = from("WorkEffort")
+                .where(workEffortId: lookedUpValue.estimatedArrivalWorkEffId)
+                .queryOne()
+        if (estimatedArrivalWorkEffort) {
+            estimatedArrivalWorkEffort.estimatedStartDate = parameters.estimatedArrivalDate
+            estimatedArrivalWorkEffort.estimatedCompletionDate = parameters.estimatedArrivalDate
+            estimatedArrivalWorkEffort.facilityId = parameters.destinationFacilityId
+            Map serviceResult = run service: "updateWorkEffort", with: estimatedArrivalWorkEffort
+            if (!ServiceUtil.isSuccess(serviceResult)) return error(serviceResult.errorMessage)
+        }
+    }
+    // if the partyIdTo or partyIdFrom has changed, add WEPAs
+    //TODO REFACTORING
+    if (parameters.partyIdFrom
+            && parameters.partyIdFrom != lookedUpValue.partyIdFrom
+            && lookedUpValue.estimatedShipWorkEffId) {
+        Map assignPartyToWorkEffortShip = [workEffortId: lookedUpValue.estimatedShipWorkEffId,
+                                           partyId: parameters.partyIdFrom]
+        List existingShipWepas = from("WorkEffortPartyAssignment")
+                .where(assignPartyToWorkEffortShip)
+                .filterByDate()
+                .queryList()
+        if (!existingShipWepas) {
+            assignPartyToWorkEffortShip.roleTypeId = "CAL_ATTENDEE"
+            assignPartyToWorkEffortShip.statusId = "CAL_SENT"
+            Map serviceResult = run service: "assignPartyToWorkEffort", with: assignPartyToWorkEffortShip
+            if (!ServiceUtil.isSuccess(serviceResult)) return error(serviceResult.errorMessage)
+        }
+    }
+    if (parameters.partyIdTo
+            && parameters.partyIdTo != lookedUpValue.partyIdTo
+            && lookedUpValue.estimatedArrivalWorkEffId) {
+        Map assignPartyToWorkEffortArrival = [workEffortId: lookedUpValue.estimatedArrivalWorkEffId,
+                                              partyId: parameters.partyIdTo]
+        List existingArrivalWepas = from("WorkEffortPartyAssignment")
+                .where(assignPartyToWorkEffortArrival)
+                .filterByDate()
+                .queryList()
+        if (!existingArrivalWepas) {
+            assignPartyToWorkEffortArrival.roleTypeId = "CAL_ATTENDEE"
+            assignPartyToWorkEffortArrival.statusId = "CAL_SENT"
+            serviceResult = run service: "assignPartyToWorkEffort", with: assignPartyToWorkEffortArrival
+            if (!ServiceUtil.isSuccess(serviceResult)) return error(serviceResult.errorMessage)
+        }
+    }
+    return result
+}
diff --git a/applications/workeffort/servicedef/services.xml b/applications/workeffort/servicedef/services.xml
index b53ef01..fb169e5 100644
--- a/applications/workeffort/servicedef/services.xml
+++ b/applications/workeffort/servicedef/services.xml
@@ -463,6 +463,18 @@ under the License.
         <attribute name="workEffortIterator" type="java.util.ListIterator" mode="IN" optional="true"/>
         <attribute name="workEfforts" type="java.util.List" mode="INOUT" optional="true"/>
     </service>
+    <service name="checkAndCreateWorkEffort" auth="true" engine="groovy" default-entity-name="Shipment"
+             location="component://workeffort/groovyScripts/workeffort/workeffort/WorkEffortServices.groovy" invoke="checkAndCreateWorkEffort">
+        <description>Check And Create WorkEffort after Shipment Create</description>
+        <auto-attributes include="pk" mode="IN" optional="false"/>
+        <auto-attributes include="nonpk" mode="IN" optional="true"/>
+    </service>
+    <service name="checkAndUpdateWorkEffort" auth="true" engine="groovy" default-entity-name="Shipment"
+             location="component://workeffort/groovyScripts/workeffort/workeffort/WorkEffortServices.groovy" invoke="checkAndUpdateWorkEffort">
+        <description>Check And Update WorkEffort after Shipment Update</description>
+        <auto-attributes include="pk" mode="IN" optional="false"/>
+        <auto-attributes include="nonpk" mode="IN" optional="true"/>
+    </service>
     <service name="getProductManufacturingSummaryByFacility" engine="java"
             location="org.apache.ofbiz.workeffort.workeffort.WorkEffortServices" invoke="getProductManufacturingSummaryByFacility">
         <description>
diff --git a/applications/workeffort/src/main/java/org/apache/ofbiz/workeffort/workeffort/WorkEffortServices.java b/applications/workeffort/src/main/java/org/apache/ofbiz/workeffort/workeffort/WorkEffortServices.java
index bb10cca..478c1bb 100644
--- a/applications/workeffort/src/main/java/org/apache/ofbiz/workeffort/workeffort/WorkEffortServices.java
+++ b/applications/workeffort/src/main/java/org/apache/ofbiz/workeffort/workeffort/WorkEffortServices.java
@@ -1107,4 +1107,4 @@ public class WorkEffortServices {
         result.put("workEfforts", resultList);
         return result;
     }
-}
+}
\ No newline at end of file