svn commit: r784195 - in /ofbiz/trunk: applications/workeffort/config/ applications/workeffort/entitydef/ applications/workeffort/servicedef/ applications/workeffort/src/org/ofbiz/workeffort/workeffort/ applications/workeffort/widget/ framework/common/...

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

svn commit: r784195 - in /ofbiz/trunk: applications/workeffort/config/ applications/workeffort/entitydef/ applications/workeffort/servicedef/ applications/workeffort/src/org/ofbiz/workeffort/workeffort/ applications/workeffort/widget/ framework/common/...

adrianc
Author: adrianc
Date: Fri Jun 12 17:03:42 2009
New Revision: 784195

URL: http://svn.apache.org/viewvc?rev=784195&view=rev
Log:
Improved iCalendar integration:

1. Work effort tasks are now converted to VTODO.
2. Event reminders can be a popup alarm
3. Fixed invalid iCalendar creation

Tested with Mozilla Sunbird. Sunbird has some annoying bugs when using read-only calendars - which they are aware of but haven't fixed. Someday I'll make the iCalendar read/write.

This commit includes a migration service for anyone who was using this feature previously.

Modified:
    ofbiz/trunk/applications/workeffort/config/WorkEffortUiLabels.xml
    ofbiz/trunk/applications/workeffort/entitydef/entitymodel.xml
    ofbiz/trunk/applications/workeffort/servicedef/services.xml
    ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalendarWorker.java
    ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/WorkEffortServices.java
    ofbiz/trunk/applications/workeffort/widget/WorkEffortForms.xml
    ofbiz/trunk/framework/common/webcommon/includes/timeDuration.ftl

Modified: ofbiz/trunk/applications/workeffort/config/WorkEffortUiLabels.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/workeffort/config/WorkEffortUiLabels.xml?rev=784195&r1=784194&r2=784195&view=diff
==============================================================================
--- ofbiz/trunk/applications/workeffort/config/WorkEffortUiLabels.xml (original)
+++ ofbiz/trunk/applications/workeffort/config/WorkEffortUiLabels.xml Fri Jun 12 17:03:42 2009
@@ -288,16 +288,16 @@
         <value xml:lang="it">Classifica</value>
         <value xml:lang="th">การประเมิณ</value>
     </property>
-    <property key="FormFieldTitle_recurrenceOffset">
-        <value xml:lang="en">Recurrence Offset</value>
-        <value xml:lang="fr">Récurrence de décalage</value>
-        <value xml:lang="it">Intervallo ricorrenza</value>
-    </property>
     <property key="FormFieldTitle_reminderDateTime">
         <value xml:lang="en">Reminder Date Time</value>
         <value xml:lang="fr">Date heure de rappel</value>
         <value xml:lang="it">Data ora reminder</value>
     </property>
+    <property key="FormFieldTitle_reminderOffset">
+        <value xml:lang="en">Reminder Offset</value>
+        <value xml:lang="fr">Récurrence de décalage</value>
+        <value xml:lang="it">Intervallo ricorrenza</value>
+    </property>
     <property key="FormFieldTitle_repeatInterval">
         <value xml:lang="en">Repeat Interval</value>
         <value xml:lang="fr">Répéter intervalle</value>

Modified: ofbiz/trunk/applications/workeffort/entitydef/entitymodel.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/workeffort/entitydef/entitymodel.xml?rev=784195&r1=784194&r2=784195&view=diff
==============================================================================
--- ofbiz/trunk/applications/workeffort/entitydef/entitymodel.xml (original)
+++ ofbiz/trunk/applications/workeffort/entitydef/entitymodel.xml Fri Jun 12 17:03:42 2009
@@ -468,17 +468,16 @@
             package-name="org.ofbiz.workeffort.workeffort"
             title="Work Effort Event Reminder Entity">
       <field name="workEffortId" type="id-ne"></field>
-      <field name="contactMechId" type="id-ne"></field>
       <field name="sequenceId" type="id-ne"></field>
+      <field name="contactMechId" type="id"></field>
       <field name="reminderDateTime" type="date-time"></field>
       <field name="repeatCount" type="numeric"></field>
       <field name="repeatInterval" type="numeric">
           <description>The millisecond interval between reminder repeats</description>
       </field>
       <field name="currentCount" type="numeric"></field>
-      <field name="recurrenceOffset" type="numeric">
-          <description>If the work effort is recurring, the millisecond offset from
-          the recurring event that will be used to calculate the reminder date/time</description>
+      <field name="reminderOffset" type="numeric">
+          <description>The millisecond offset from the event to activate a reminder</description>
       </field>
       <field name="localeId" type="id"></field>
       <field name="timeZoneId" type="id-long"></field>

Modified: ofbiz/trunk/applications/workeffort/servicedef/services.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/workeffort/servicedef/services.xml?rev=784195&r1=784194&r2=784195&view=diff
==============================================================================
--- ofbiz/trunk/applications/workeffort/servicedef/services.xml (original)
+++ ofbiz/trunk/applications/workeffort/servicedef/services.xml Fri Jun 12 17:03:42 2009
@@ -685,6 +685,10 @@
             location="org.ofbiz.workeffort.workeffort.WorkEffortServices" invoke="processWorkEffortEventReminders" auth="true">
         <description>Process work effort event reminders. This service is run by the job scheduler.</description>
     </service>
+    <service name="migrateWorkEffortEventReminders" engine="java"
+            location="org.ofbiz.workeffort.workeffort.WorkEffortServices" invoke="migrateWorkEffortEventReminders" auth="true">
+        <description>Migrate work effort event reminders. Run this service to update work effort reminders.</description>
+    </service>
     
     <!-- WorkEffort and Survey Services -->
     <service name="createWorkEffortSurveyAppl" engine="simple" default-entity-name="WorkEffortSurveyAppl"

Modified: ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalendarWorker.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalendarWorker.java?rev=784195&r1=784194&r2=784195&view=diff
==============================================================================
--- ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalendarWorker.java (original)
+++ ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalendarWorker.java Fri Jun 12 17:03:42 2009
@@ -19,9 +19,11 @@
 
 package org.ofbiz.workeffort.workeffort;
 
+import java.net.URISyntaxException;
+import java.sql.Timestamp;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
-import java.util.TimeZone;
 
 import javolution.util.FastList;
 
@@ -34,40 +36,69 @@
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.TimeDuration;
 import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilProperties;
 import org.ofbiz.base.util.UtilValidate;
 import org.ofbiz.entity.GenericDelegator;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.entity.condition.EntityCondition;
-import org.ofbiz.entity.condition.EntityConditionList;
 import org.ofbiz.entity.condition.EntityExpr;
 import org.ofbiz.entity.condition.EntityOperator;
 import org.ofbiz.entity.util.EntityUtil;
 import org.ofbiz.service.calendar.TemporalExpression;
 import org.ofbiz.service.calendar.TemporalExpressionWorker;
 
-/** iCalendar worker class. */
+/** iCalendar worker class. This class uses the <a href="http://ical4j.sourceforge.net/index.html">
+ * iCal4J</a> library. */
 public class ICalendarWorker {
     public static final String module = ICalendarWorker.class.getName();
-    protected static ProdId prodId = new ProdId("-//Apache Open For Business//Work Effort Calendar//EN");
-    protected static Map<String, Status> statusMap = UtilMisc.toMap("CAL_TENTATIVE", Status.VEVENT_TENTATIVE,
+    
+    protected static final ProdId prodId = new ProdId("-//Apache Open For Business//Work Effort Calendar//EN");
+    protected static final Map<String, Status> statusMap = UtilMisc.toMap("CAL_TENTATIVE", Status.VEVENT_TENTATIVE,
             "CAL_CONFIRMED", Status.VEVENT_CONFIRMED, "CAL_CANCELLED", Status.VEVENT_CANCELLED);
-    protected static String workEffortIdPropName = "X-ORG-OFBIZ-WORKEFFORT-ID";
+    protected static final String uidPrefix = "org-apache-ofbiz-we-";
 
+    /** Returns a calendar derived from a Work Effort calendar publish point.
+     *
+     * @param delegator
+     * @param workEffortId ID of a work effort with <code>workEffortTypeId</code> equal to
+     * <code>PUBLISH_PROPS</code>.
+     * @return A <code>net.fortuna.ical4j.model.Calendar</code> instance, or <code>null</code>
+     * if <code>workEffortId</code> is invalid.
+     * @throws GenericEntityException
+     */
     public static net.fortuna.ical4j.model.Calendar getICalendar(GenericDelegator delegator, String workEffortId) throws GenericEntityException {
-        GenericValue calendarProperties = delegator.findByPrimaryKey("WorkEffort", UtilMisc.toMap("workEffortId", workEffortId));
-        if (calendarProperties == null || !"PUBLISH_PROPS".equals(calendarProperties.get("workEffortTypeId"))) {
+        GenericValue publishProperties = delegator.findByPrimaryKey("WorkEffort", UtilMisc.toMap("workEffortId", workEffortId));
+        if (publishProperties == null || !"PUBLISH_PROPS".equals(publishProperties.get("workEffortTypeId"))) {
             return null;
         }
-        net.fortuna.ical4j.model.Calendar calendar = makeCalendar(calendarProperties);
+        net.fortuna.ical4j.model.Calendar calendar = makeCalendar(publishProperties);
         ComponentList components = calendar.getComponents();
-        List<GenericValue> workEfforts = getRelatedWorkEfforts(calendarProperties);
+        List<GenericValue> workEfforts = getRelatedWorkEfforts(publishProperties);
         for (GenericValue workEffort : workEfforts) {
-            components.add(makeEvent(workEffort));
+            components.add(makeCalendarComponent(workEffort));
+        }
+        if (Debug.verboseOn()) {
+            try {
+                calendar.validate(true);
+                Debug.logVerbose("iCalendar passes validation", module);
+            } catch (ValidationException e) {
+                Debug.logVerbose("iCalendar fails validation: " + e, module);
+            }
         }
         return calendar;
     }
 
+    /** Returns a <code>List</code> of work efforts related to a work effort calendar
+     * publish point.<p>The <code>List</code> includes:<ul><li>All public work efforts of all
+     * parties related to the publish point work effort</li><li>All public work efforts
+     * of all fixed assets related to the publish point work effort</li><li>All
+     * child work efforts of the publish point work effort</li></ul></p>
+     *
+     * @param workEffort
+     * @return A <code>List</code> of related work efforts
+     * @throws GenericEntityException
+     */
     public static List<GenericValue> getRelatedWorkEfforts(GenericValue workEffort) throws GenericEntityException {
         GenericDelegator delegator = workEffort.getDelegator();
         String workEffortId = workEffort.getString("workEffortId");
@@ -93,7 +124,15 @@
         return WorkEffortWorker.removeDuplicateWorkEfforts(workEfforts);
     }
 
-    public static VEvent makeEvent(GenericValue workEffort) throws GenericEntityException {
+    /** Returns a <code>Component</code> instance based on a work effort.
+     * If the work effort is a task, then a <code>VToDo</code> is returned,
+     * otherwise a <code>VEvent</code> is returned.
+     *
+     * @param workEffort
+     * @return A <code>VToDo</code> or <code>VEvent</code> instance
+     * @throws GenericEntityException
+     */
+    public static Component makeCalendarComponent(GenericValue workEffort) throws GenericEntityException {
         GenericDelegator delegator = workEffort.getDelegator();
         String workEffortId = workEffort.getString("workEffortId");
         PropertyList eventProps = new PropertyList();
@@ -104,7 +143,7 @@
         if (workEffort.getTimestamp("lastModifiedDate") != null) {
             eventProps.add(new LastModified(new DateTime(workEffort.getTimestamp("lastModifiedDate"))));
         }
-        eventProps.add(new XProperty(workEffortIdPropName, workEffort.getString("workEffortId")));
+        eventProps.add(new Uid(uidPrefix.concat(workEffortId)));
         eventProps.add(new Summary(workEffort.getString("workEffortName")));
         Status eventStatus = statusMap.get(workEffort.getString("currentStatusId"));
         if (eventStatus != null) {
@@ -126,9 +165,9 @@
             // paramList.add(new XParameter(partyIdPropName, partyValue.getString("partyId")));
             try {
                 if ("CAL_ORGANIZER~CAL_OWNER".contains(partyValue.getString("roleTypeId"))) {
-                    eventProps.add(new Organizer(paramList, ""));
+                    eventProps.add(new Organizer("CN:".concat(partyName)));
                 } else {
-                    eventProps.add(new Attendee(paramList, ""));
+                    eventProps.add(new Attendee("CN:".concat(partyName)));
                 }
             } catch (Exception e) {}
         }
@@ -152,20 +191,42 @@
         if (workEffort.getString("description") != null) {
             eventProps.add(new Description(workEffort.getString("description")));
         }
-        return new VEvent(eventProps);
+        ComponentList alarms = null;
+        Component result = null;
+        if ("TASK".equals(workEffort.get("workEffortTypeId"))) {
+            VToDo toDo = new VToDo(eventProps);
+            alarms = toDo.getAlarms();
+            result = toDo;
+        } else {
+            VEvent event = new VEvent(eventProps);
+            alarms = event.getAlarms();
+            result = event;
+        }
+        getAlarms(workEffort, alarms);
+        if (Debug.verboseOn()) {
+            try {
+                result.validate(true);
+                Debug.logVerbose("iCalendar component passes validation", module);
+            } catch (ValidationException e) {
+                Debug.logVerbose("iCalendar component fails validation: " + e, module);
+            }
+        }
+        return result;
     }
 
+    /** Returns a new <code>net.fortuna.ical4j.model.Calendar</code> instance,
+     * based on a work effort calendar publish point.
+     *
+     * @param workEffort
+     * @return
+     * @throws GenericEntityException
+     */
     public static net.fortuna.ical4j.model.Calendar makeCalendar(GenericValue workEffort) throws GenericEntityException {
         net.fortuna.ical4j.model.Calendar calendar = new net.fortuna.ical4j.model.Calendar();
         PropertyList propList = calendar.getProperties();
         propList.add(prodId);
         propList.add(Version.VERSION_2_0);
         propList.add(CalScale.GREGORIAN);
-        if (workEffort.get("description") != null) {
-            propList.add(new Description(workEffort.getString("description")));
-        } else {
-            propList.add(new Description(workEffort.getString("workEffortName")));
-        }
         // TODO: Get time zone from publish properties value
         java.util.TimeZone tz = java.util.TimeZone.getDefault();
         TimeZoneRegistry registry = TimeZoneRegistryFactory.getInstance().createRegistry();
@@ -173,4 +234,72 @@
         calendar.getComponents().add(timezone.getVTimeZone());
         return calendar;
     }
+
+    /** Converts <code>WorkEffortEventReminder</code> entities to <code>VAlarm</code>
+     * instances, and adds them to a <code>ComponentList</code>.
+     *
+     * @param workEffort The work effort to get the event reminders for
+     * @param alarms The <code>ComponentList</code> that will contain the
+     * <code>VAlarm</code> instances
+     * @throws GenericEntityException
+     */
+    public static void getAlarms(GenericValue workEffort, ComponentList alarms) throws GenericEntityException {
+        Description description = null;
+        if (workEffort.get("description") != null) {
+            description = new Description(workEffort.getString("description"));
+        } else {
+            description = new Description(workEffort.getString("workEffortName"));
+        }
+        Summary summary = new Summary(UtilProperties.getMessage("WorkEffortUiLabels", "WorkEffortEventReminder", Locale.getDefault()));
+        GenericDelegator delegator = workEffort.getDelegator();
+        List<GenericValue> reminderList = delegator.findList("WorkEffortEventReminder", EntityCondition.makeCondition("workEffortId", EntityOperator.EQUALS, workEffort.get("workEffortId")), null, null, null, false);
+        for (GenericValue reminder : reminderList) {
+            VAlarm alarm = createAlarm(reminder);
+            PropertyList alarmProps = alarm.getProperties();
+            GenericValue contactMech = reminder.getRelatedOne("ContactMech");
+            if (contactMech != null && "EMAIL_ADDRESS".equals(contactMech.get("contactMechTypeId"))) {
+                try {
+                    alarmProps.add(new Attendee(contactMech.getString("infoString")));
+                    alarmProps.add(Action.EMAIL);
+                    alarmProps.add(summary);
+                    alarmProps.add(description);
+                } catch (URISyntaxException e) {
+                    alarmProps.add(Action.DISPLAY);
+                    alarmProps.add(new Description("Error encountered while creating iCalendar: " + e));
+                }
+            } else {
+                alarmProps.add(Action.DISPLAY);
+                alarmProps.add(description);
+            }
+            if (Debug.verboseOn()) {
+                try {
+                    alarm.validate(true);
+                    Debug.logVerbose("iCalendar alarm passes validation", module);
+                } catch (ValidationException e) {
+                    Debug.logVerbose("iCalendar alarm fails validation: " + e, module);
+                }
+            }
+            alarms.add(alarm);
+        }
+    }
+
+    /** Converts a <code>WorkEffortEventReminder</code> entity to a
+     * <code>VAlarm</code> instance.
+     *
+     * @param workEffortEventReminder
+     * @return A <code>VAlarm</code> instance
+     * @throws GenericEntityException
+     */
+    public static VAlarm createAlarm(GenericValue workEffortEventReminder) {
+        VAlarm alarm = null;
+        Timestamp reminderStamp = workEffortEventReminder.getTimestamp("reminderDateTime");
+        if (reminderStamp != null) {
+            alarm = new VAlarm(new DateTime(reminderStamp));
+        } else {
+            long reminderOffset = workEffortEventReminder.get("reminderOffset") == null ? 0 : workEffortEventReminder.getLong("reminderOffset").longValue();
+            TimeDuration duration = TimeDuration.fromLong(reminderOffset);
+            alarm = new VAlarm(new Dur(duration.days(), duration.hours(), duration.minutes(), duration.seconds()));
+        }
+        return alarm;
+    }
 }

Modified: ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/WorkEffortServices.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/WorkEffortServices.java?rev=784195&r1=784194&r2=784195&view=diff
==============================================================================
--- ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/WorkEffortServices.java (original)
+++ ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/WorkEffortServices.java Fri Jun 12 17:03:42 2009
@@ -49,6 +49,8 @@
 import org.ofbiz.entity.condition.EntityExpr;
 import org.ofbiz.entity.condition.EntityJoinOperator;
 import org.ofbiz.entity.condition.EntityOperator;
+import org.ofbiz.entity.model.ModelEntity;
+import org.ofbiz.entity.model.ModelField;
 import org.ofbiz.entity.util.EntityUtil;
 import org.ofbiz.security.Security;
 import org.ofbiz.service.DispatchContext;
@@ -747,6 +749,9 @@
             return ServiceUtil.returnError("Error while retrieving work effort event reminders: " + e);
         }
         for (GenericValue reminder : eventReminders) {
+            if (UtilValidate.isEmpty(reminder.get("contactMechId"))) {
+                continue;
+            }
             int repeatCount = reminder.get("repeatCount") == null ? 0 : reminder.getLong("repeatCount").intValue();
             int currentCount = reminder.get("currentCount") == null ? 0 : reminder.getLong("currentCount").intValue();
             GenericValue workEffort = null;
@@ -780,11 +785,11 @@
                 if (temporalExpression != null) {
                     eventDateTime = temporalExpression.first(cal).getTime();
                     Date reminderDateTime = null;
-                    long recurrenceOffset = reminder.get("recurrenceOffset") == null ? 0 : reminder.getLong("recurrenceOffset").longValue();
+                    long reminderOffset = reminder.get("reminderOffset") == null ? 0 : reminder.getLong("reminderOffset").longValue();
                     if (reminderStamp == null) {
-                        if (recurrenceOffset != 0) {
+                        if (reminderOffset != 0) {
                             cal.setTime(eventDateTime);
-                            TimeDuration duration = TimeDuration.fromLong(recurrenceOffset);
+                            TimeDuration duration = TimeDuration.fromLong(reminderOffset);
                             duration.addToCalendar(cal);
                             reminderDateTime = cal.getTime();
                         } else {
@@ -802,11 +807,11 @@
                             } else {
                                 cal.setTime(reminderDateTime);
                                 Date newReminderDateTime = null;
-                                if (recurrenceOffset != 0) {
-                                    TimeDuration duration = TimeDuration.fromLong(-recurrenceOffset);
+                                if (reminderOffset != 0) {
+                                    TimeDuration duration = TimeDuration.fromLong(-reminderOffset);
                                     duration.addToCalendar(cal);
                                     cal.setTime(temporalExpression.next(cal).getTime());
-                                    duration = TimeDuration.fromLong(recurrenceOffset);
+                                    duration = TimeDuration.fromLong(reminderOffset);
                                     duration.addToCalendar(cal);
                                     newReminderDateTime = cal.getTime();
                                 } else {
@@ -876,4 +881,30 @@
         // TODO: Other contact mechanism types
         Debug.logWarning("Invalid event reminder contact mech, workEffortId = " + reminder.get("workEffortId") + ", contactMechId = " + reminder.get("contactMechId"), module);
     }
+
+    /** Migrate work effort event reminders.
+     * @param ctx
+     * @param context
+     * @return
+     */
+    @SuppressWarnings("deprecation")
+    public static Map<String, Object> migrateWorkEffortEventReminders(DispatchContext ctx, Map<String, ? extends Object> context) {
+        GenericDelegator delegator = ctx.getDelegator();
+        ModelEntity modelEntity = delegator.getModelEntity("WorkEffortEventReminder");
+        if (modelEntity != null && modelEntity.getField("recurrenceOffset") != null) {
+            List<GenericValue> eventReminders = null;
+            try {
+                eventReminders = delegator.findAll("WorkEffortEventReminder");
+                for (GenericValue reminder : eventReminders) {
+                    if (UtilValidate.isNotEmpty(reminder.get("recurrenceOffset"))) {
+                        reminder.set("reminderOffset", reminder.get("recurrenceOffset"));
+                        reminder.store();
+                    }
+                }
+            } catch (GenericEntityException e) {
+                return ServiceUtil.returnError("Error while migrating work effort event reminders: " + e);
+            }
+        }
+        return ServiceUtil.returnSuccess();
+    }
 }

Modified: ofbiz/trunk/applications/workeffort/widget/WorkEffortForms.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/workeffort/widget/WorkEffortForms.xml?rev=784195&r1=784194&r2=784195&view=diff
==============================================================================
--- ofbiz/trunk/applications/workeffort/widget/WorkEffortForms.xml (original)
+++ ofbiz/trunk/applications/workeffort/widget/WorkEffortForms.xml Fri Jun 12 17:03:42 2009
@@ -1309,7 +1309,7 @@
         <field name="reminderDateTime"><date-time/></field>
         <field name="repeatCount"><text/></field>
         <field name="repeatInterval"><text/></field>
-        <field name="recurrenceOffset"><text/></field>
+        <field name="reminderOffset"><text/></field>
         <field name="submitButton" title="${uiLabelMap.CommonSave}" widget-style="smallSubmit"><submit button-type="button"/></field>
         <field name="deleteLink" title="${uiLabelMap.CommonEmptyHeader}" widget-style="buttontext">
            <hyperlink also-hidden="false" description="${uiLabelMap.CommonDelete}" target="deleteWorkEffortEventReminder">
@@ -1325,11 +1325,11 @@
         <field name="workEffortId"><hidden/></field>
         <field name="localeId"><hidden value="${locale}"/></field>
         <field name="timeZoneId"><hidden value="${timeZone}"/></field>
-        <field name="contactMechId" tooltip="${uiLabelMap.CommonRequired}" widget-style="required"><lookup target-form-name="LookupContactMech"/></field>
+        <field name="contactMechId"><lookup target-form-name="LookupContactMech"/></field>
         <field name="reminderDateTime"><date-time/></field>
         <field name="repeatCount"><text/></field>
         <field name="repeatInterval"><text/></field>
-        <field name="recurrenceOffset"><text/></field>
+        <field name="reminderOffset"><lookup target-form-name="LookupTimeDuration"/></field>
         <field name="submitButton" title="${uiLabelMap.CommonAdd}" widget-style="smallSubmit"><submit button-type="button"/></field>
     </form>
 

Modified: ofbiz/trunk/framework/common/webcommon/includes/timeDuration.ftl
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/webcommon/includes/timeDuration.ftl?rev=784195&r1=784194&r2=784195&view=diff
==============================================================================
--- ofbiz/trunk/framework/common/webcommon/includes/timeDuration.ftl (original)
+++ ofbiz/trunk/framework/common/webcommon/includes/timeDuration.ftl Fri Jun 12 17:03:42 2009
@@ -44,7 +44,7 @@
     </tr>
     <tr>
       <td class="label">${uiLabelMap.CommonWeek}</td>
-      <td><input type="text" name="weeks" maxlength="2"/></td>
+      <td><input type="text" name="weeks" size="4" maxlength="2"/></td>
     </tr>
     <tr>
       <td class="label">${uiLabelMap.CommonDay}</td>
@@ -88,7 +88,7 @@
     </tr>
     <tr>
       <td class="label">${uiLabelMap.CommonMilliSecond}</td>
-      <td><input type="text" name="millis" maxlength="4"/></td>
+      <td><input type="text" name="millis" size="4" maxlength="4"/></td>
     </tr>
     <tr>
       <td>&nbsp;</td>