1   package hudsonfog.voc.model;
2   
3   import com.fogx.webdav.DavResource;
4   import com.fogx.webdav.DavClass;
5   import com.fogx.webdav.DavBean;
6   import com.fogx.webdav.DavProperty;
7   import static com.fogx.webdav.DavProperty.*;
8   import com.fogx.webdav.packages.DavBeanPackage;
9   import com.fogx.webdav.util.DavResourceSupport;
10  import com.fogx.webdav.util.UrlUtil;
11  import java.util.Date;
12  import java.util.Map;
13  import java.util.HashMap;
14  import java.util.List;
15  import java.util.Collections;
16  import java.util.Arrays;
17  
18  import hudsonfog.voc.system.changeHistory.*;
19  import hudsonfog.voc.model.crm.*;
20  import hudsonfog.voc.model.company.*;
21  import hudsonfog.voc.system.primitiveTypes.*;
22  import hudsonfog.voc.model.recurrence.*;
23  import hudsonfog.voc.model.portal.*;
24  import hudsonfog.voc.model.work.*;
25  import hudsonfog.voc.system.parse.*;
26  import hudsonfog.voc.model.top.*;
27  import hudsonfog.voc.model.workflow.*;
28  import hudsonfog.voc.system.XMLSchema.*;
29  
30  import hudsonfog.voc.system.fog.*;
31  
32  
33  public abstract class workflow {
34  
35    /**
36   * Workflow messages are not email-born, they are fully authenticated and typed
37   */
38    @DavClass._label("Message")
39    public static class IncomingWorkflowMessage extends hudsonfog.voc.system.parse.IncomingMessage implements Annotated {
40           @_displayNameElm
41      @k@s public String                        subject;
42      @k@s public ComplexDate                   dateReceived;
43           @_backLink("forum")
44           @_displayInline
45        @c public Annotation[]                  comments;
46        @c public Annotation                    lastComment;
47           @_backLink("forResource")
48           @_displayInline
49        @c public ChatHistoryFile[]             chatHistory;
50           @_dateFormat("~MMM-dd, yyyy HH:mm")
51           @_readOnly
52           @_icon("icons/classes/Comment.gif")
53           public ComplexDate                   lastCommentTime = formula("lastComment.submitTime");
54           @_backLink("message")
55           public TimeEntryPerMessage[]         timeEntries;
56        @s public Contact                       sender;
57        @s public Contact                       to;
58    }
59  
60    /**
61   * Message associated with the specific Contact
62   */
63    @DavClass._label("Email")
64    public static class IncomingMailMessage extends hudsonfog.voc.system.parse.IncomingMessage {
65           @_displayNameElm
66      @k@s public String                        subject;
67      @k@s public ComplexDate                   dateReceived;
68           @_maxSize(200)
69           public String                        messageId; //* message id assigned by the mail server
70           @_maxSize(60000)
71           public longString                    messageHeaders; //* message headers
72    }
73  
74    /**
75   * Workflow message for registration by email. Valid for skip access control classes where registerByEmail is true
76   */
77    @DavClass._label("Auto-Registration")
78    public static class AutoRegistrationAlert extends IncomingWorkflowMessage {
79           @_displayNameElm
80      @k@s public String                        subject;
81      @k@s public ComplexDate                   dateReceived;
82    }
83  
84    /**
85   * Workflow message associated with the specific CollaborationPoint
86   */
87    @DavClass._label("Message")
88    public static class CollaborationMessage extends IncomingWorkflowMessage {
89           @_displayNameElm
90      @k@s public String                        subject;
91      @k@s public ComplexDate                   dateReceived;
92           @_subPropertyOf("associatedWith")
93        @s public CollaborationPoint            forum; //* forum with which this message is associated
94    }
95  
96    /**
97   * Instant message that could not be delivered since user was offline.
98   */
99    public static class OfflineMessage extends IncomingWorkflowMessage {
100          @_displayNameElm
101     @k@s public String                        subject;
102     @k@s public ComplexDate                   dateReceived;
103   }
104 
105   @DavClass._largeIcon("icons/classes/Subscription-large.gif")
106   @DavClass._icon("icons/classes/Subscription.gif")
107   public static class SubscriptionInvitation extends CollaborationMessage {
108          @_displayNameElm
109     @k@s public String                        subject;
110     @k@s public ComplexDate                   dateReceived;
111          public dateTime                      dateAccepted = writeJS("setSubscribed()");
112          public MySubscription                subscription;
113          public Boolean                       accepted;
114          @_backLink("message")
115     @h@s public TimeEntryPerMessage[]         timeEntries;
116   }
117 
118   @DavClass._largeIcon("icons/classes/SubscriptionAlert-large.gif")
119   @DavClass._icon("icons/classes/SubscriptionAlert.gif")
120   public static class SubscriptionAlert extends CollaborationMessage {
121          @_displayNameElm
122     @k@s public String                        subject;
123     @k@s public ComplexDate                   dateReceived;
124          public MySubscription                subscription;
125   }
126 
127   @DavClass._largeIcon("icons/classes/CommentAlert-large.gif")
128   @DavClass._icon("icons/classes/CommentAlert.gif")
129   public static class CommentAlert extends CollaborationMessage {
130          @_displayNameElm
131     @k@s public String                        subject;
132     @k@s public ComplexDate                   dateReceived;
133          public Note                          comment;
134   }
135 
136   public static class MeetingAlert extends ReminderAlert {
137     @k@s public String                        subject = writeJS("formatDate() + ' meeting ' + meeting.title");
138     @k@s public ComplexDate                   dateReceived;
139     @k@s public Contact                       to;
140          @_subPropertyOf("forum")
141       @s public Meeting                       meeting;
142   }
143 
144   @DavClass._largeIcon("icons/classes/New-large.gif")
145   @DavClass._icon("icons/classes/New.gif")
146   public static class NewResourceAlert extends CollaborationMessage {
147          @_displayNameElm
148     @k@s public String                        subject;
149     @k@s public ComplexDate                   dateReceived;
150   }
151 
152   @DavClass._largeIcon("icons/classes/ModificationAlert-large.gif")
153   @DavClass._icon("icons/classes/ModificationAlert.gif")
154   public static class ModificationAlert extends CollaborationMessage {
155          @_displayNameElm
156     @k@s public String                        subject;
157     @k@s public ComplexDate                   dateReceived;
158          public Modification                  modification;
159          @_icon("icons/description.gif")
160          @_displayInline
161          public String                        editNotes = formula("modification.editNotes");
162   }
163 
164   @DavClass._largeIcon("icons/classes/ReminderAlert-large.gif")
165   @DavClass._icon("icons/classes/ReminderAlert.gif")
166   public static class ReminderAlert extends CollaborationMessage {
167          @_displayNameElm
168     @k@s public String                        subject = writeJS("'reminder: ' + formatDate() + ': ' + forum.subject");
169     @k@s public ComplexDate                   dateReceived;
170          public ScheduledItem                 scheduledItem;
171          public dateTime                      start; //* scheduled event starts
172          public dateTime                      end; //* scheduled event ends
173   }
174 
175   @DavClass._largeIcon("icons/classes/ReminderAlert-large.gif")
176   @DavClass._icon("icons/classes/ReminderAlert.gif")
177   public static class InvitationAlert extends CollaborationMessage {
178          @_displayNameElm
179     @k@s public String                        subject;
180     @k@s public ComplexDate                   dateReceived;
181          public Boolean                       accepted; //* yes, if you accepted this invitation
182   }
183 
184   /**
185  * System alert - abnormal system condition (like disk out of space) that endagers operations or stability of the server
186  */
187   public static class SystemAlert extends IncomingWorkflowMessage {
188       @k public Integer                       seq;
189     @k@s public Contact                       to;
190       @s public String                        subject;
191       @s public ComplexDate                   dateReceived;
192   }
193 
194   public static class AssignmentAlert extends CollaborationMessage {
195          @_displayNameElm
196     @k@s public String                        subject;
197     @k@s public ComplexDate                   dateReceived;
198          public PartyAssignment               assignment;
199          public WorkEffort                    workEffort = formula("assignment.workEffort");
200          @_backLink("message")
201       @s public TimeEntryPerAssignmentAlert[] timeEntries;
202   }
203 
204   public static class PartyResourceAlert extends CollaborationMessage {
205          @_displayNameElm
206     @k@s public String                        subject;
207     @k@s public ComplexDate                   dateReceived;
208          public PartyResource                 partyResource;
209          @_readOnly
210          @_subPropertyOf("forum")
211       @s public WorkEffort                    mainWorkEffort = writeJS("partyResource.mainWorkEffort");
212   }
213 
214   /**
215  * While in general TimeEntry is related to a WorkEffort or a TimeSheet,
216  * this TimeEntry allows a lot more granular time accounting.
217  * Several entries can be created for one Message.
218  * Work can be attributed to an Incoming or an OutgoingMessage.
219  */
220   public static class TimeEntryPerMessage extends hudsonfog.voc.model.work.TimeEntry {
221     @k@s public Integer                       seq;
222          @_readOnly
223     @k@s public Contact                       contact = writeJS("setContact()");
224          public IncomingWorkflowMessage       message; //* this time entry is recorded when a single message required significant amount of work
225   }
226 
227   /**
228  * While in general TimeEntry is related to a WorkEffort or a TimeSheet,
229  * this TimeEntry allows a lot more granular time accounting.
230  * Several entries can be created for one Message.
231  * Work can be attributed to an Incoming or an OutgoingMessage.
232  */
233   public static class TimeEntryPerAssignmentAlert extends TimeEntryPerMessage {
234     @k@s public Integer                       seq;
235       @s public AssignmentAlert               message; //* message that required this effort
236     @k@s public Contact                       contact;
237          public WorkAssignment                assignment = formula("message.assignment");
238          @_notifyContainer
239          public WorkEffort                    workEffort = formula("assignment.workEffort"); //* Assignment's Work Effort
240          @_notifyContainer
241          public WorkEffort                    mainWorkEffort = formula("workEffort.mainWorkEffort"); //* this time entry is recorded per 'main Effort', e.g. Project
242   }
243 
244   @DavClass._largeIcon("icons/classes/ApprovalRequest-large.gif")
245   @DavClass._icon("icons/classes/ApprovalRequest.gif")
246   public static class ApprovalRequest extends hudsonfog.voc.model.top.Demand implements ScheduledItem {
247          @_subPropertyOf("forum")
248     @k@s public CollaborationPoint            itemToApprove;
249          @_displayNameElm
250          @_subPropertyOf("synopsis")
251     @r@s public String                        title;
252     @k@s public ComplexDate                   dateSubmitted;
253          @_subPropertyOf("description")
254       @s public String                        notes;
255          @_backLink("request")
256          @_displayInline
257          @_extractSubscribers // approvers will be invited to subscribe
258          public Approval[]                    approvals; //* people that must approve this item
259          @_readOnly
260          public Boolean                       approved = writeJS("approved != null? approved: unconfirmedApprovals.COUNT() == 0 ? true : false"); //* If approvers approve the request, the Approved field is set to Yes. If any approver rejects/returns the request, this field remains set to No.
261          @_readOnly
262          @_backLink("request")
263          public UnconfirmedApproval[]         unconfirmedApprovals;
264          @_readOnly
265          public Integer                       unconfirmedApprovalCount = writeJS("unconfirmedApprovals.COUNT()");
266       @s public ComplexDate                   deadline; //* deadline by which decision must be reached
267   }
268 
269   /**
270  * Approval request that is sent to each approver (as a part of an Approval Request with multiple approvers).
271  */
272   @DavClass._viewCols("request, approver, status, deadline, itemToApprove")
273   @DavClass._largeIcon("icons/classes/Approval-large.gif")
274   @DavClass._icon("icons/classes/Approval.gif")
275   public static class Approval implements ScheduledItem {
276       @k public ApprovalRequest               request;
277       @k public Integer                       seq;
278       @r public Contact                       approver; //* person whose approval is requested
279          @_icon("icons/Status.gif")
280          @_colorCoding("'Requested' icons/status_requested.gif; 'Approved' icons/classes/ApprovalMessage.gif; 'Rejected' icons/classes/RejectedMessage.gif; 'Returned' icons/classes/ReturnedMessage.gif; ")
281          @_onCreate
282          public ApprovalStatus                status = writeJS("status ? status : 'Requested'"); //* decision that approver made for this approval request
283          @_icon("icons/deadline.gif")
284          @_cloneOf("end")
285       @c public dateTime                      deadline; //* deadline by which decision must be reached
286          public DavResource                   itemToApprove = formula("request.itemToApprove"); //* item for approval
287   }
288 
289   public static enum ApprovalStatus {
290     Requested, Approved, Rejected, Returned;
291   }
292 
293   @DavClass._aView
294   @DavClass._avoidEditing
295   @DavClass._where("status != 'Approved'")
296   @DavClass._filterView
297   public static class UnconfirmedApproval extends Approval {
298     @h@s public ApprovalRequest               request;
299     @h@s public Integer                       seq;
300     @h@s public Contact                       approver;
301     @h@s public ApprovalStatus                status;
302     @h@s public dateTime                      deadline;
303     @h@s public DavResource                   itemToApprove;
304   }
305 
306   /**
307  * Alert that is sent to approver when approval is requested.
308  */
309   public static class ApprovalAlert extends IncomingWorkflowMessage {
310          @_displayNameElm
311     @k@s public String                        subject;
312          @_subPropertyOf("to")
313       @s public Contact                       approver;
314          @_subPropertyOf("sender")
315       @s public Contact                       requestedBy;
316     @k@s public ComplexDate                   dateReceived;
317          @_subPropertyOf("associatedWith")
318       @s public Approval                      approval; //* place to record your decision
319          public DavResource                   itemToApprove = formula("approval.itemToApprove"); //* actual item to be approved
320          public ApprovalRequest               request = formula("approval.request"); //* approval request sent to possibly more than one approver
321   }
322 
323   /**
324  * Indicates that notifications on this resource must be confirmed by the partner.
325  * Notification is sent via email.
326  * Confirmation of receipt is done simply by viewing the resource.
327  */
328   public static interface ReceiptRequested {
329          public Integer                       days = null;
330          public Integer                       hours = null; // time constraint - max time allocated to confirm
331          public Integer                       minutes = null;
332          public Boolean                       received = null; // indicates that receipt was received.
333             // If change tracking is on - change history will indicate when recieved and by whom.
334          public Contact                       recipient = null;
335   }
336 
337   /**
338  * Indicates that this resource must be confirmed by the partner.
339  * Confirmation of receipt is done simply by modifying the resource online.
340  */
341   public static interface ConfirmationRequested extends ReceiptRequested {
342          public Boolean                       confirmed = null; // indicates that resource was confirmed.
343             // If change tracking is on - change history will indicate when confirmed and by whom.
344   }
345 }
346