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.model.company
.*;
19
import
hudsonfog.voc.model.humanResources
.*;
20
import
hudsonfog.voc.model.products
.*;
21
import
hudsonfog.voc.system.fog
.*;
22
import
hudsonfog.voc.model.accounting
.*;
23
import
hudsonfog.voc.system.behavior
.*;
24
import
hudsonfog.voc.model.recurrence
.*;
25
import
hudsonfog.voc.model.portal
.*;
26
import
hudsonfog.voc.model.work
.*;
27
import
hudsonfog.voc.system.parse
.*;
28
import
hudsonfog.voc.model.crm
.*;
29
import
hudsonfog.voc.system.primitiveTypes
.*;
30
import
hudsonfog.voc.model.orders
.*;
31
import
hudsonfog.voc.model.workplace
.*;
32
import
hudsonfog.voc.model.workflow
.*;
33
import
hudsonfog.voc.model.top
.*;
34
import
hudsonfog.voc.system.XMLSchema
.*;
35
36
import
hudsonfog.voc.system.fog
.*;
37
38
39
public
abstract
class
work {
40
41
/**
42
* Work order constitutes a committment to deliver services
43
*/
44
public
static
class
WorkOrder
extends
hudsonfog.voc.model.top.Order
{
45
@
k
@s
public
String synopsis;
46
@
k
@s
public
ComplexDate dateSubmitted;
47
public
OrderType orderType;
48
public
Organization internalClient;
//* internal customer
49
@_maxDisplayInplace(
5
)
50
@_backLink(
"order"
)
51
public
Deliverable[] deliverables;
//* agreed upon deliverables
52
@_maxDisplayInplace(
5
)
53
@_backLink(
"order"
)
54
@_allowRoles(
"owner"
)
55
public
InternalDeliverable[] internalDeliverables;
//* deliverables that are not shown to the outside people
56
@_maxDisplayInplace(
5
)
57
@_backLink(
"cause"
)
58
public
WorkEffort[] efforts;
//* efforts that fulfill this order
59
@_subPropertyOf(
"deadline"
)
60
@s
public
ComplexDate requiredByDate;
61
}
62
63
public
static
enum OrderType {
64
@_label(
"New order"
) NewOrder, @_label(
"Change order"
) ChangeOrder;
65
}
66
67
/**
68
* Work effort, like repair/maintenance of an equipment, production run, task, etc.
69
*/
70
@DavClass._viewCols(
"title, start, finish, description, assignments, issues, timeEntries, lastModified, lastCommentTime, touched, myUnreadMessages, myFlaggedMessages, sizeOfAttachments, attachments"
)
71
@DavClass._largeIcon(
"icons/classes/WorkEffort-large.gif"
)
72
@DavClass._icon(
"icons/classes/WorkEffort.gif"
)
73
public
static
class
WorkEffort
extends
hudsonfog.voc.model.top.Need
implements
ScheduledItem, FolderItem {
74
@_displayNameElm
75
@_subPropertyOf(
"synopsis"
)
76
@
k
@s
public
String title;
77
@
k
@s
public
ComplexDate dateSubmitted;
78
@_icon(
"icons/classes/WorkEffort.gif"
)
79
@_makeTotal
80
public
Duration work;
//* amount of time needed to complete work
81
@_icon(
"icons/classes/Money.gif"
)
82
@_makeTotal
83
public
Money cost;
//* cost of this work
84
@_icon(
"icons/percentWorkComplete.gif"
)
85
@_scale(
0
)
// formula not needed anymore since != 100 respects null; = WRITE_JS(percentWorkComplete == null? 0: percentWorkComplete);
86
public
Percent percentWorkComplete;
//* how much work was already done
87
public
CollaborationPoint cause;
//* request or other cause that initiated this effort
88
@h@s
public
CollaborationPoint forum;
//* the workplace this effort is associated with
89
@_cloneOf(
"rootFolder"
)
90
@c
public
WorkEffort mainWorkEffort;
//* this work effort my be associated with a main work effort, like project for task
91
@_dateFormat(
"~MMM-dd, yyyy HH:mm"
)
92
@c
public
ComplexDate start;
//* target start date
93
@_dateFormat(
"~MMM-dd, yyyy HH:mm"
)
94
@_cloneOf(
"end"
)
95
@c
public
ComplexDate finish;
//* when to finish
96
@c
public
Boolean cancelled;
97
@_backLink(
"scheduledItem"
)
98
@c
public
ReminderAlert[] reminders;
//* reminder alerts that have been sent for this item
99
@_dateFormat(
"~MMM-dd, yyyy HH:mm"
)
100
@_icon(
"icons/actualStart.gif"
)
101
public
Long actualStart;
//* when work actually started
102
@_dateFormat(
"~MMM-dd, yyyy HH:mm"
)
103
@_icon(
"icons/actualEnd.gif"
)
104
public
Long actualFinish;
//* when work was actually completed
105
@_backLink(
"workEffort"
)
106
public
WorkAssignment[] assignments;
107
@_backLink(
"workEffort"
)
108
public
TimeEntryPerEffort[] timeEntries;
109
@_backLink(
"workEffort"
)
110
public
FixedCostAssignment[] fixedCostAssignments;
111
@_backLink(
"mainWorkEffort"
)
112
public
PartyResource[] peopleResources;
113
@_avoidDisplaying
114
public
Contact resourceContact = formula(
"peopleResources.contact"
);
// listed people resources - has access to this work effort
115
@_makeTotal
116
@_icon(
"icons/actualWork.gif"
)
117
public
Duration actualWork = writeJS(
"getThisChange().actualWork ? actualWork: getThisChange().timeEntries ? timeEntries.SUM('work') : actualWork"
);
//* by entering the explicit number you will override the value automatically calculated based on time entries
118
@_icon(
"icons/actualCost.gif"
)
119
@_makeTotal
120
public
Money actualCost = writeJS(
"getThisChange().actualCost ? actualCost: getThisChange().timeEntries ? timeEntries.SUM('cost') : actualCost"
);
//* by entering the explicit number you will override the value automatically calculated based on time entries
121
@_onCreate
122
@_colorCoding(
"'Medium' icons/priority_normal.gif; 'High' icons/priority_major.gif; 'Highest' icons/priority_critical.gif; 'Lowest' icons/priority_trivial.gif; 'Low' icons/priority_minor.gif"
)
123
@s
public
TaskPriority priority = writeJS(
"priority ? priority: 'Medium'"
);
124
@_backLink(
"forum"
)
125
public
Issue[] issues;
//* issues registered for this work effort
126
}
127
128
/**
129
* Production run is a kind of WorkEffort that records the activity of producing certain product quantity
130
*/
131
public
static
class
ProductionRun
extends
WorkEffort {
132
@h@s
public
String title;
133
@h@s
public
ComplexDate dateSubmitted;
134
@
k
public
Integer id;
135
public
OrderItem orderItem;
136
public
ton quantityToProduce;
137
}
138
139
public
static
class
WorkAssignment
implements
ScheduledItem, FolderItem {
140
@_displayNameElm
141
@
k
public
WorkResource workResource;
//* person or an asset
142
@_cloneOf(
"folder"
)
143
@
k
@c
public
WorkEffort workEffort;
144
@c
public
ComplexDate start;
//* when to start working on it
145
@_cloneOf(
"end"
)
146
@c
public
ComplexDate finish;
//* when to finish
147
@_scale(
0
)
148
public
Percent units;
//* utilization - percentage of allocated time the resource will be on this assignment
149
@_icon(
"icons/percentComplete.gif"
)
150
@_scale(
0
)
151
public
Percent percentComplete;
//* tracks actual use of this resource assignment
152
@_icon(
"icons/actualStart.gif"
)
153
public
Long actualStart;
//* when work actually started
154
@_icon(
"icons/actualEnd.gif"
)
155
public
Long actualFinish;
//* when work was actually completed
156
@_maxSize(
2000
)
157
@_icon(
"icons/description.gif"
)
158
public
String comment;
159
@_icon(
"icons/Status.gif"
)
160
@_colorCoding(
"'Requested' icons/status_requested.gif; 'Confirmed' icons/classes/ApprovalMessage.gif; 'Rejected' icons/classes/RejectedMessage.gif"
)
161
@_onCreate
162
public
AssignmentStatus status;
//* if resource is a material - it may be allocated or not
163
@_cloneOf(
"rootFolder"
)
164
@c
public
WorkEffort mainWorkEffort;
165
@_abstract
166
@c
public
ComplexDate groupby;
167
@_readOnly
168
@c
public
Boolean conflict;
//* system detected overallocation of resources for this assigment
169
@c
public
Boolean cancelled;
170
}
171
172
public
static
enum AssignmentStatus {
173
Requested, Allocated, Denied;
174
}
175
176
public
static
enum PartyAssignmentStatus {
177
Requested, Confirmed, Rejected;
178
}
179
180
@DavClass._viewCols(
"partyResource, workEffort, start, status"
)
181
@DavClass._largeIcon(
"icons/classes/PartyAssignment-large.gif"
)
182
@DavClass._icon(
"icons/classes/PartyAssignment.gif"
)
183
public
static
class
PartyAssignment
extends
WorkAssignment {
184
@_displayNameElm
185
@_subPropertyOf(
"workResource"
)
186
@
k
@s
public
PartyResource partyResource;
187
@
k
@s
public
WorkEffort workEffort;
188
@
r
public
Position role;
189
public
Contact contact = formula(
"partyResource.contact"
);
190
public
PartyAssignmentType partyAssignmentType;
191
@_backLink(
"assignment"
)
192
public
TimeEntryPerAssignment[] timeEntries;
//* time accounting
193
@_icon(
"icons/actualWork.gif"
)
194
@_makeTotal
195
public
Duration actualWork = writeJS(
"getThisChange().actualWork ? actualWork: getThisChange().timeEntries ? timeEntries.SUM('work') : actualWork"
);
//* by entering the explicit number you will override the value automatically calculated based on time entries
196
@_makeTotal
197
@_icon(
"icons/actualCost.gif"
)
198
public
Money actualCost = writeJS(
"getThisChange().actualCost ? actualCost: getThisChange().timeEntries ? timeEntries.SUM('cost') : actualCost"
);
//* by entering the explicit number you will override the value automatically calculated based on time entries
199
@s
public
PartyAssignmentStatus status;
//* person may decide to confirm or reject the assignment;
200
}
201
202
public
static
enum PartyAssignmentRole {
203
@_label(
"Project Manager"
) ProjectManager, @_label(
"Web Developer"
) WebDeveloper, @_label(
"App Developer"
) AppDeveloper, @_label(
"DB Developer"
) DBDeveloper, @_label(
"Data architect"
) DataArchitect, @_label(
"System Architect"
) SystemArchitect, @_label(
"Test Designer"
) TestDesigner, Tester, @_label(
"Business Analyst"
) BusinessAnalyst, @_label(
"End User"
) EndUser, @_label(
"SA/Coordinator"
) SA_Coordinator, SysAdmin, @_label(
"Business Owner"
) BusinessOwner;
204
}
205
206
public
static
enum PartyAssignmentType {
207
@_label(
"Department staff member"
) DepartmentStaffMember, @_label(
"Member of another department"
) MemberOfAnotherDepartment, @_label(
"Not a staff member"
) NotAStaffMember;
208
}
209
210
/**
211
* Some work efforts may require various kinds of equipment, software or other property - Fixed Asset.
212
*/
213
public
static
class
AssetAssignment
extends
WorkAssignment {
214
@_displayNameElm
215
@_subPropertyOf(
"workResource"
)
216
@
k
@s
public
AssetResource assetResource;
217
@
k
@s
public
WorkEffort workEffort;
218
}
219
220
/**
221
* Unqualified fixed cost assignment
222
*/
223
public
static
class
FixedCostAssignment
extends
WorkAssignment {
224
@_displayNameElm
225
@
k
public
String name;
226
@h@s
public
WorkResource workResource;
227
@
k
@s
public
WorkEffort workEffort;
228
@_icon(
"icons/classes/Money.gif"
)
229
public
Money cost;
230
@_maxSize(
100
)
231
public
String budgetaryBucket;
232
}
233
234
/**
235
* WorkResource is an element in the Project resource pool.
236
* WorkResources can represent Staff members or Assets.
237
* Used as a reference to a Contact (or Asset) to defer setting a specific Contact and
238
* to allow easy replacement of Contact during the planning stage of the work effort.
239
* Replacement is easy since you can change Contact in one place - WorkResource,
240
* and not in every WorkAssignment where this Contact would have been mentioned.
241
*/
242
public
static
class
WorkResource
implements
FolderItem, Cancellable {
243
@_readOnly
244
@
k
public
Integer seq;
245
@_cloneOf(
"rootFolder"
)
246
@
k
@c
public
WorkEffort mainWorkEffort;
// points to a main (top) work effort, like project
247
@_maxSize(
50
)
248
@_displayNameElm
249
@
k
public
String name;
250
@_maxSize(
250
)
251
public
String notes;
252
public
DavResource forResource;
253
@_backLink(
"workResource"
)
254
public
WorkAssignment[] assignments;
//* assignments that point to this resource
255
@c
public
Boolean cancelled;
256
}
257
258
@DavClass._largeIcon(
"icons/classes/Contact-large.gif"
)
259
@DavClass._icon(
"icons/classes/Contact.gif"
)
260
public
static
class
PartyResource
extends
WorkResource {
261
@
k
@s
public
Integer seq;
262
@
k
@s
public
WorkEffort mainWorkEffort;
263
@_displayNameElm
264
@s
public
String name;
265
@_displayNameElm
266
@_subPropertyOf(
"forResource"
)
267
@s
public
Contact contact;
268
}
269
270
@DavClass._largeIcon(
"icons/classes/AssetResource-large.gif"
)
271
@DavClass._icon(
"icons/classes/AssetResource.gif"
)
272
public
static
class
AssetResource
extends
WorkResource {
273
@
k
@s
public
Integer seq;
274
@
k
@s
public
WorkEffort mainWorkEffort;
275
@_displayNameElm
276
@s
public
String name;
277
@_displayNameElm
278
@_subPropertyOf(
"forResource"
)
279
@s
public
FixedAsset asset;
280
}
281
282
/**
283
* Time entry is used to track the time spent by the person on a work effort.
284
* Note: The person may have done work, while not formally assigned.
285
* Note. Does not force TimeEntry to be associated with a particular TimeSheet.
286
*/
287
@DavClass._largeIcon(
"icons/classes/TimeSheetItem-large.gif"
)
288
@DavClass._icon(
"icons/classes/TimeSheetItem.gif"
)
289
public
static
class
TimeEntry
implements
ScheduledItem {
290
@_displayNameElm
291
@_onCreate
292
@
k
public
Contact contact = writeJS(
"contact ? contact : getContact()"
);
293
@
k
public
Integer seq;
294
@_displayNameElm
295
@c
public
ComplexDate start;
//* day/time work started
296
@_readOnly
297
@_icon(
"icons/week.gif"
)
298
public
ComplexDate weekEnding = writeJS(
" getFriday(start.date).getTime() "
);
299
@_icon(
"icons/classes/WorkEffort.gif"
)
300
@_makeTotal
301
@
r
public
Duration work;
//* amount of time recorded
302
@_cloneOf(
"end"
)
303
@c
public
ComplexDate finish;
//* when finished
304
@_makeTotal
305
@_icon(
"icons/classes/Money.gif"
)
306
@_readOnly
307
public
Money cost = writeJS(
"basedOnBudgetItem && work != null && basedOnBudgetItem.hourlyRate != null? work/3600 * basedOnBudgetItem.hourlyRate : null"
);
308
public
WorkBudgetItem basedOnBudgetItem;
309
public
Position position = formula(
"basedOnBudgetItem.position"
);
310
@_maxSize(
1000
)
311
@_icon(
"icons/description.gif"
)
312
public
String comment;
313
}
314
315
/**
316
* This TimeEntry allows time accounting on per work effort basis.
317
*/
318
public
static
class
TimeEntryPerEffort
extends
TimeEntry
implements
FolderItem {
319
@
k
@s
public
Integer seq;
320
@_readOnly
321
@
k
@s
public
Contact contact;
322
@_notifyContainer
323
@_cloneOf(
"folder"
)
324
@
r
@c
public
WorkEffort workEffort;
//* this time entry is recorded per Work Effort, e.g. Task
325
@_notifyContainer
326
@_cloneOf(
"rootFolder"
)
327
@c
public
WorkEffort mainWorkEffort = formula(
"workEffort.mainWorkEffort"
);
//* this time entry is recorded per 'main Effort', e.g. Project
328
}
329
330
/**
331
* This TimeEntry allows a lot more granular time accounting on per assignment basis.
332
*/
333
public
static
class
TimeEntryPerAssignment
extends
TimeEntryPerEffort {
334
@
k
@s
public
Integer seq;
335
@_onCreate
336
@
k
@s
public
Contact contact = writeJS(
"setContact()"
);
337
@_notifyContainer
338
@
r
public
PartyAssignment assignment;
//* this time entry is recorded per Work Assignment
339
@s
public
WorkEffort workEffort = formula(
"assignment.workEffort"
);
//* Assignment's Work Effort
340
}
341
342
public
static
class
TimeSheet {
343
@_autoincrement
344
@
k
public
Integer id;
345
@_icon(
"icons/start.gif"
)
346
public
Long fromDate;
347
@_icon(
"icons/end.gif"
)
348
public
Long thruDate;
349
@_maxSize(
5000
)
350
public
String comment;
351
@_backLink(
"timeSheet"
)
352
public
TimeEntryPerTimeSheet[] timeEntries;
353
@_onCreate
354
public
TimeSheetStatus status = writeJS(
"status == null ? 'Not completed' : status"
);
355
}
356
357
public
static
enum TimeSheetStatus {
358
@_label(
"Not completed"
) NotCompleted, Completed;
359
}
360
361
/**
362
* This TimeEntry allows time accounting on per work effort basis.
363
*/
364
public
static
class
TimeEntryPerTimeSheet
extends
TimeEntry
implements
FolderItem {
365
@
k
@s
public
Integer seq;
366
@_readOnly
367
@
k
@s
public
Contact contact;
368
@_notifyContainer
369
@
r
public
TimeSheet timeSheet;
//* this time entry is recorded per Timesheet
370
}
371
372
/**
373
* Todo captures an effort that does not require detailed breakdown into sub-work-efforts.
374
* Use for simple efforts, otherwise consider more structured Projects & Tasks.
375
*/
376
public
static
class
Todo
extends
WorkEffort {
377
@_displayNameElm
378
@
k
@s
public
String title;
379
@
k
@s
public
ComplexDate dateSubmitted;
380
public
Product product;
//* product for which the work must be done
381
public
ProductComponent productComponent;
//* product part for which work must be done
382
@s
public
CollaborationPoint cause;
//* request (like order, issue) or ther cause that initiated this todo item
383
public
Contact assignedTo;
384
}
385
386
/**
387
* Project is a work effort with subordinate tasks and their subtasks
388
*/
389
@DavClass._viewCols(
"name, startDate, finishDate, notes, tasks, assignments, issues, timeEntries, lastModified, lastCommentTime, touched, myUnreadMessages, myFlaggedMessages, sizeOfAttachments, attachments"
)
390
@DavClass._largeIcon(
"icons/classes/Project-large.gif"
)
391
@DavClass._icon(
"icons/classes/Project.gif"
)
392
public
static
class
Project
extends
WorkEffort
implements
Folder, Templatable {
393
@_displayNameElm
394
@_displaySize(
35
)
395
@_subPropertyOf(
"title"
)
396
@
k
@s
public
String name;
//* projects have to have unique names
397
@_subPropertyOf(
"dateSubmitted"
)
398
@s
public
ComplexDate dateCreated;
399
@_maxSize(
1000
)
400
public
String subjectName;
//* additional keywords, like category, client, purpose, etc.
401
@_backLink(
"project"
)
402
@_displayInline
403
@_cloneOf(
"folderItems"
)
404
@c
public
Task[] tasks;
405
@_cloneOf(
"parentFolder"
)
406
@c
public
WorkItem workItem;
407
@_subPropertyOf(
"description"
)
408
@s
public
String notes;
409
@_sortAscending(
false
)
410
@_subPropertyOf(
"start"
)
411
@s
public
ComplexDate startDate;
412
@_subPropertyOf(
"finish"
)
413
@s
public
ComplexDate finishDate;
414
@_backLink(
"project"
)
415
@s
public
ProjectResource[] peopleResources;
416
@_backLink(
"project"
)
417
@s
public
TaskAssignment[] assignments;
// assume for now only people assigments (until we figure out how to determine the type of assignment in MS Project)
418
@c
public
Project basedOnTemplate;
//* allows to choose a template for this resource at the time of its creation
419
@c
public
Boolean isTemplate;
//* allows to mark this Project as a template
420
@_backLink(
"project"
)
421
public
TaskDependency[] dependencies;
422
@_backLink(
"associatedWith"
)
423
public
News[] news;
424
@_backLink(
"forum"
)
425
public
BookmarkItem[] bookmarks;
426
@_backLink(
"forum"
)
427
@s
public
Issue[] issues;
//* issues registered for this project
428
@_backLink(
"mainForum"
)
429
public
Issue[] taskIssues;
//* issues on individual tasks
430
@_notSearchable
431
@_backLink(
"forum"
)
432
public
Meeting[] meetings;
433
@_notSearchable
434
@_backLink(
"associatedWith"
)
435
public
Forum[] forums;
436
@_subPropertyOf(
"forum"
)
437
@s
public
Workplace workplace;
//* the workplace this project is associated with
438
@_backLink(
"mainWorkEffort"
)
439
@s
public
TimeEntryPerEffort[] timeEntries;
440
@_subPropertyOf(
"mainWorkEffort"
)
441
@s
public
Project masterProject;
//* master project governs several related projects
442
}
443
444
/**
445
* Task is a work effort that is part of some Project. Use to track through completion a personal, work-related duty or an errand. <br><b>Note.</b> For simpler tasks that are not part of some Project - use <b>Todo</b> instead.
446
*/
447
@DavClass._chartViewCols(
"name, duration, start, percentComplete"
)
448
@DavClass._viewCols(
"name, project, duration, start, priority, assignments, issues, percentComplete, percentWorkComplete, timeEntries, touched, myUnreadMessages, myFlaggedMessages, sizeOfAttachments, attachments, work, actualWork, cost, actualCost"
)
449
@DavClass._largeIcon(
"icons/classes/Project-large.gif"
)
450
@DavClass._icon(
"icons/classes/Task.gif"
)
451
public
static
class
Task
extends
WorkEffort
implements
Folder {
452
@_displayNameElm
453
@_displaySize(
35
)
454
@_propertyEditor(
"FolderResourcePropertyEditor"
)
455
@_subPropertyOf(
"title"
)
456
@
r
@s
public
String name;
457
@_subPropertyOf(
"mainWorkEffort"
)
458
@
k
@s
public
Project project;
//* project this task belongs to
459
@_notSearchable
460
@
k
public
Integer seq;
461
@_notifyContainer
462
@_cloneOf(
"parentFolder"
)
463
@c
public
Task parentTask;
464
@_subPropertyOf(
"description"
)
465
@s
public
String notes;
466
@s
public
Duration work;
// = WRITE_JS(onWork());
467
@_readOnly
468
@s
public
Money cost;
469
public
Duration duration;
// = WRITE_JS(onDuration());
470
@s
public
ComplexDate start;
471
@s
public
ComplexDate finish;
472
@_icon(
"icons/overtimeWork.gif"
)
473
public
Duration overtimeWork;
474
@_icon(
"icons/overtimeCost.gif"
)
475
@_readOnly
476
public
Money overtimeCost;
477
@s
public
Duration actualWork;
478
@s
public
Money actualCost;
479
public
Duration actualDuration;
480
@s
public
Long actualStart;
481
@s
public
Long actualFinish;
482
@_readOnly
483
public
Money actualOvertimeCost;
484
public
Duration actualOvertimeWork;
485
@_readOnly
486
public
Money remainingCost = writeJS(
"cost != null && actualCost != null? cost - actualCost : null"
);
487
@_readOnly
488
public
Duration remainingDuration;
489
@_readOnly
490
public
Money remainingOvertimeCost;
491
@_readOnly
492
public
Duration remainingOvertimeWork;
493
@_readOnly
494
public
Duration remainingWork = writeJS(
"work != null && actualCost != null? work - actualWork : null"
);
495
@_readOnly
496
public
Integer unconfirmedAssignmentsCount = writeJS(
"getThisChange().unconfirmedAssignments ? unconfirmedAssignments.COUNT() : unconfirmedAssignmentsCount"
);
497
@_readOnly
498
public
Boolean confirmed = writeJS(
"getThisChange().unconfirmedAssignments ? unconfirmedAssignmentsCount : confirmed"
);
//* If all resources accept the task assignment, the Confirmed field is set to Yes. If any resource rejects the assignment, this field remains set to No.
499
@_readOnly
500
@_backLink(
"task"
)
501
public
UnconfirmedTaskAssignment[] unconfirmedAssignments;
502
public
Boolean critical;
//* A task that must be completed on schedule for the project to finish on time.<br>If a critical task is delayed, the project completion date might also be delayed. <br>A series of critical tasks makes up a project's critical path.
503
public
Boolean milestone;
//* task marked in MS Project: "Mark Task as Milestone";
504
@_onCreate
505
public
ConstraintType constraintType = writeJS(
"constraintType ? constraintType : 'As Soon As Possible'"
);
506
public
Long constraintDate;
507
@_maxSize(
40
)
508
@_notSearchable
509
public
String contact;
//* Name of an individual responsible for a task. This person can be someone other than the assigned resource.
510
@_subPropertyOf(
"dateSubmitted"
)
511
@s
public
ComplexDate created;
512
@s
public
ComplexDate deadline;
// boolean fixed; not clear what this is, may be fixedAccrual?
513
@_readOnly
514
public
Money fixedCost;
515
@_readOnly
516
public
Integer outlineLevel;
517
@_maxSize(
40
)
518
@_sortAscending
519
@_readOnly
520
public
String outlineNumber;
521
@_icon(
"icons/percentComplete.gif"
)
522
@_scale(
0
)
523
public
Percent percentComplete = writeJS(
"percentComplete != null ? percentComplete : (actualDuration == null || duration == null) ? null : (actualDuration / duration) * 100"
);
//* completion according to duration
524
@_icon(
"icons/percentWorkComplete.gif"
)
525
@_scale(
0
)
526
@s
public
Percent percentWorkComplete;
// completion of work
527
@s
public
TaskPriority priority;
528
@_icon(
"icons/pause.gif"
)
529
public
Long stop;
530
@_icon(
"icons/resume.gif"
)
531
public
Long resume;
532
@_icon(
"icons/resume.gif"
)
533
public
Long resumeNoEarlierThan;
534
public
Duration freeSlack;
//* how much a task can slip before it delays another task
535
public
Duration totalSlack;
//* how much a task can slip before it delays the project
536
@_onCreate
537
public
TaskType taskType = writeJS(
"taskType ? taskType: 'Fixed units'"
);
538
@_readOnly
539
@_immutable
540
@_notSearchable
541
public
Integer uniqueID;
//* id assigned to a task by MS Project
542
@_backLink(
"task"
)
543
@_subPropertyOf(
"assignments"
)
544
@s
public
TaskAssignment[] taskAssignments;
545
@_avoidDisplaying
546
public
Contact assignmentsContact = formula(
"taskAssignments.contact"
);
// who has assignments - has access to this work effort
547
@_backLink(
"parentTask"
)
548
@_cloneOf(
"folderItems"
)
549
@c
public
Task[] subtasks;
550
@_largeIcon(
"icons/classes/Successor-large.gif"
)
551
@_icon(
"icons/classes/Successor.gif"
)
552
@_backLink(
"from"
)
553
public
TaskDependency[] successors;
//* required for tasks
554
@_largeIcon(
"icons/classes/Predecessor-large.gif"
)
555
@_icon(
"icons/classes/Predecessor.gif"
)
556
@_backLink(
"to"
)
557
public
TaskDependency[] predecessors;
//* depends on tasks
558
@_readOnly
559
@_backLink(
"workEffort"
)
560
public
AssignmentAlert[] assignmentAlerts;
561
@_backLink(
"workEffort"
)
562
@s
public
TimeEntryPerAssignment[] timeEntries;
563
@h@s
public
CollaborationPoint cause;
// individual tasks do not have a cause, only a main effort - Project
564
}
565
566
public
static
enum TaskPriority {
567
Lowest, @_label(
"Very Low"
) VeryLow, Lower, Low, Medium, High, Higher, @_label(
"Very High"
) VeryHigh, Highest;
568
}
569
570
public
static
enum ConstraintType {
571
@_label(
"As Soon As Possible"
) AsSoonAsPossible, @_label(
"As Late As Possible"
) AsLateAsPossible, @_label(
"Finish No Later Than"
) FinishNoLaterThan, @_label(
"Finish No Earlier Than"
) FinishNoEarlierThan, @_label(
"Must Finish On"
) MustFinishOn, @_label(
"Must Start On"
) MustStartOn, @_label(
"Start No Earlier Than"
) StartNoEarlierThan, @_label(
"Start No Later Than"
) StartNoLaterThan;
572
}
573
574
public
static
enum TaskType {
575
@_label(
"Fixed duration"
) FixedDuration, @_label(
"Fixed units"
) FixedUnits, @_label(
"Fixed work"
) FixedWork;
576
}
577
578
/**
579
* Assignment of some individual or an organization (represented by a contact)
580
* to a task.
581
*/
582
@DavClass._viewCols(
"projectResource, task, project, units, work, start, finish, status, timeEntries"
)
583
@DavClass._chartViewCols(
"name, contact, task"
)
584
@DavClass._editCols(
"projectResource, units, work, actualWork, actualCost, start, finish, status"
)
585
public
static
class
TaskAssignment
extends
PartyAssignment {
586
@_displayNameElm
587
@_subPropertyOf(
"workEffort"
)
588
@
k
@s
public
Task task;
589
@_displayNameElm
590
@_subPropertyOf(
"partyResource"
)
591
@
k
@s
public
ProjectResource projectResource;
592
public
String name = formula(
"projectResource.name"
);
593
@s
public
Contact contact;
594
@_subPropertyOf(
"mainWorkEffort"
)
595
@s
public
Project project;
596
@_icon(
"icons/classes/WorkEffort.gif"
)
597
public
Duration work;
// = WRITE_JS(onWork());
598
@_makeTotal
599
@_readOnly
600
@_icon(
"icons/classes/Money.gif"
)
601
public
Money cost;
602
public
Duration delay;
603
@_icon(
"icons/overtimeWork.gif"
)
604
public
Duration overtimeWork;
605
@s
public
Money actualCost;
//* actual cost to this moment
606
@s
public
Duration actualWork;
//* actual work done to this moment
607
public
Money plannedCost;
//* baseline cost
608
public
Duration plannedWork;
//* baseline work
609
@s
public
Position role;
// subproperty it to clear the 'required'
610
@_backLink(
"assignment"
)
611
@s
public
TimeEntryPerAssignment[] timeEntries;
//* time accounting per task assignment
612
}
613
614
@DavClass._aView
615
@DavClass._filterView
616
public
static
class
Allocation
extends
TaskAssignment {
617
@_displayNameElm
618
@s
public
Task task;
619
@s
public
ProjectResource projectResource;
620
@s
public
String name;
621
@_displayNameElm
622
@s
public
Contact contact;
623
@s
public
Project project;
624
@s
public
Position role;
625
@s
public
ComplexDate start;
626
@s
public
ComplexDate finish;
627
@_abstract
628
@s
public
ComplexDate groupby;
629
@_makeTotal
630
@_colorCoding(
"0-80 green; 80-100 black; 100-10000 red"
)
631
@s
public
Percent units;
632
@_makeTotal(
false
)
633
@s
public
Money actualCost;
//* actual cost to this moment
634
@_makeTotal(
false
)
635
@s
public
Duration actualWork;
//* actual work done to this moment
636
@_makeTotal(
false
)
637
@s
public
Money cost;
638
@h@s
public
Duration work;
639
@h@s
public
Duration delay;
640
@h@s
public
Duration overtimeWork;
641
@h@s
public
Money plannedCost;
642
@h@s
public
Duration plannedWork;
643
@_backLink(
"assignment"
)
644
@h@s
public
TimeEntryPerAssignment[] timeEntries;
645
@h@s
public
PartyAssignmentType partyAssignmentType;
646
@h@s
public
PartyAssignmentStatus status;
647
@h@s
public
Percent percentComplete;
648
@h@s
public
Long actualStart;
649
@h@s
public
Long actualFinish;
650
@h@s
public
String comment;
651
@h@s
public
Boolean conflict;
652
@h@s
public
Boolean cancelled;
653
}
654
655
@DavClass._aView
656
@DavClass._chartViewCols(
"contact, task"
)
657
@DavClass._filterView
658
public
static
class
AllocationPerContact
extends
Allocation {
659
}
660
661
@DavClass._aView
662
@DavClass._viewCols(
"name, task, project, units, work, start, finish, status, timeEntries"
)
663
@DavClass._chartViewCols(
"name"
)
664
@DavClass._filterView
665
public
static
class
AllocationPerRole
extends
Allocation {
666
}
667
668
@DavClass._aView
669
@DavClass._chartViewCols(
"task, project"
)
670
@DavClass._groupBy(
"task"
)
671
@DavClass._filterView
672
public
static
class
AllocationPerProject
extends
TaskAssignment {
673
@s
public
Task task;
674
@_displayNameElm
675
@s
public
ProjectResource projectResource;
676
@s
public
String name;
677
@s
public
Contact contact;
678
@s
public
Project project;
679
@s
public
Position role;
680
@s
public
ComplexDate start;
681
@s
public
ComplexDate finish;
682
@_makeTotal
683
@_colorCoding(
"0-80 green; 80-100 black; 100-10000 red"
)
684
@s
public
Percent units;
685
@h@s
public
Duration work;
686
@h@s
public
Money cost;
687
@h@s
public
Duration delay;
688
@h@s
public
Duration overtimeWork;
689
@h@s
public
Money actualCost;
690
@h@s
public
Duration actualWork;
691
@h@s
public
Money plannedCost;
692
@h@s
public
Duration plannedWork;
693
@_backLink(
"assignment"
)
694
@h@s
public
TimeEntryPerAssignment[] timeEntries;
695
@h@s
public
PartyAssignmentType partyAssignmentType;
696
@h@s
public
PartyAssignmentStatus status;
697
@h@s
public
Percent percentComplete;
698
@h@s
public
Long actualStart;
699
@h@s
public
Long actualFinish;
700
@h@s
public
String comment;
701
@h@s
public
ComplexDate groupby;
702
@h@s
public
Boolean conflict;
703
@h@s
public
Boolean cancelled;
704
}
705
706
@DavClass._aView
707
@DavClass._largeIcon(
"icons/classes/Project-large.gif"
)
708
@DavClass._viewCols(
"startDate, finishDate, project"
)
709
@DavClass._groupBy(
"project, contact"
)
710
@DavClass._icon(
"icons/classes/Project.gif"
)
711
@DavClass._filterView
712
public
static
class
MyProject
extends
TaskAssignment {
713
@s
public
Contact contact;
714
@s
public
Project project;
715
public
ComplexDate startDate = formula(
"project.startDate"
);
716
public
ComplexDate finishDate = formula(
"project.finishDate"
);
717
@h@s
public
Task task;
718
@h@s
public
ProjectResource projectResource;
719
@h@s
public
String name;
720
@h@s
public
Duration work;
721
@h@s
public
Money cost;
722
@h@s
public
Duration delay;
723
@h@s
public
Duration overtimeWork;
724
@h@s
public
Money actualCost;
725
@h@s
public
Duration actualWork;
726
@h@s
public
Money plannedCost;
727
@h@s
public
Duration plannedWork;
728
@h@s
public
Position role;
729
@_backLink(
"assignment"
)
730
@h@s
public
TimeEntryPerAssignment[] timeEntries;
731
@h@s
public
PartyAssignmentType partyAssignmentType;
732
@h@s
public
PartyAssignmentStatus status;
733
@h@s
public
ComplexDate start;
734
@h@s
public
ComplexDate finish;
735
@h@s
public
Percent units;
736
@h@s
public
Percent percentComplete;
737
@h@s
public
Long actualStart;
738
@h@s
public
Long actualFinish;
739
@h@s
public
String comment;
740
@h@s
public
ComplexDate groupby;
741
@h@s
public
Boolean conflict;
742
@h@s
public
Boolean cancelled;
743
}
744
745
@DavClass._aView
746
@DavClass._avoidEditing
747
@DavClass._where(
"status != 'Confirmed'"
)
748
@DavClass._filterView
749
public
static
class
UnconfirmedTaskAssignment
extends
TaskAssignment {
750
@h@s
public
Task task;
751
@h@s
public
ProjectResource projectResource;
752
@h@s
public
String name;
753
@h@s
public
Contact contact;
754
@h@s
public
Project project;
755
@h@s
public
Duration work;
756
@h@s
public
Money cost;
757
@h@s
public
Duration delay;
758
@h@s
public
Duration overtimeWork;
759
@h@s
public
Money actualCost;
760
@h@s
public
Duration actualWork;
761
@h@s
public
Money plannedCost;
762
@h@s
public
Duration plannedWork;
763
@h@s
public
Position role;
764
@_backLink(
"assignment"
)
765
@h@s
public
TimeEntryPerAssignment[] timeEntries;
766
@h@s
public
PartyAssignmentType partyAssignmentType;
767
@h@s
public
PartyAssignmentStatus status;
768
@h@s
public
ComplexDate start;
769
@h@s
public
ComplexDate finish;
770
@h@s
public
Percent units;
771
@h@s
public
Percent percentComplete;
772
@h@s
public
Long actualStart;
773
@h@s
public
Long actualFinish;
774
@h@s
public
String comment;
775
@h@s
public
ComplexDate groupby;
776
@h@s
public
Boolean conflict;
777
@h@s
public
Boolean cancelled;
778
}
779
780
@DavClass._viewCols(
"name, contact, project, notes, maxUnits, work, percentWorkComplete, assignments"
)
781
public
static
class
ProjectResource
extends
PartyResource {
782
@_subPropertyOf(
"mainWorkEffort"
)
783
@
k
@s
public
Project project;
784
@
k
@s
public
Integer seq;
785
@_displayNameElm
786
@s
public
String name;
787
@_displayNameElm
788
@_copyByReference
789
@s
public
Contact contact;
790
@_icon(
"icons/classes/WorkEffort.gif"
)
791
public
Duration work;
792
@_makeTotal
793
@_icon(
"icons/classes/Money.gif"
)
794
public
Money cost;
795
@_icon(
"icons/classes/Money.gif"
)
796
public
Money costVariance;
797
public
String emailAddress;
798
@_maxSize(
40
)
799
public
String group;
800
public
Float maxUnits;
801
@s
public
String notes;
802
@_icon(
"icons/overtimeCost.gif"
)
803
public
Money overtimeCost;
804
@_icon(
"icons/overtimeWork.gif"
)
805
public
Duration overtimeWork;
806
public
Float peak;
807
@_icon(
"icons/percentWorkComplete.gif"
)
808
@_scale(
0
)
// formula not needed anymore since != 100 works with null too; = WRITE_JS(percentWorkComplete == null ? 0: percentWorkComplete);
809
public
Percent percentWorkComplete;
//* how much work was already done
810
public
Duration regularWork;
811
public
Money remainingCost;
812
public
Money remainingOvertimeCost;
813
public
Duration remainingWork;
814
public
ResourceCalendar resourceCalendar;
815
@_notSearchable
816
@_immutable
817
public
Integer uniqueID;
818
public
Money actualOvertimeCost;
819
public
ResourceCalendar baseCalendar;
820
@_maxSize(
40
)
821
public
String code;
822
@_backLink(
"projectResource"
)
823
@s
public
TaskAssignment[] assignments;
824
}
825
826
@DavClass._cachable
827
public
static
class
BaseCalendar {
828
@
k
public
String name;
// "Standard, 24 hours, Night Shift";
829
@_backLink(
"forResource"
)
830
@_displayInline
831
public
Available[] available;
832
@_backLink(
"forResource"
)
833
@_displayInline
834
public
Unavailable[] unavailable;
835
@_avoidDisplaying
836
@_backLink(
"forResource"
)
837
public
CalendarItem[] allItems;
838
}
839
840
@DavClass._viewCols(
"name, contact, available, unavailable, isTemplate"
)
841
@DavClass._largeIcon(
"icons/classes/ResourceCalendar-large.gif"
)
842
@DavClass._icon(
"icons/classes/ResourceCalendar.gif"
)
843
public
static
class
ResourceCalendar
extends
BaseCalendar
implements
Templatable {
844
@_autoincrement
845
@_readOnly
846
@
k
public
Integer id;
847
@_displayNameElm
848
@
r
@s
public
String name;
// "Standard, 24 hours, Night Shift";
849
@_displayNameElm
850
@_readOnly
851
@_containerMember
852
@_forwardLink(
"http://www.hudsonfog.com/voc/model/company/Contact/myCalendars"
)
853
public
Contact contact;
854
@_immutable
855
@_cloneOf(
"basedOnTemplate"
)
856
@_onCreate
857
@c
public
ResourceCalendar copiedFromCalendar;
//* the original template resource
858
@c
public
Boolean isTemplate;
//* id calendar is marked as template - other calendars can be copied from it
859
}
860
861
/**
862
* Working hours of the organization
863
*/
864
@DavClass._viewCols(
"organization, open, closed"
)
865
@DavClass._largeIcon(
"icons/classes/ResourceCalendar-large.gif"
)
866
@DavClass._icon(
"icons/classes/ResourceCalendar.gif"
)
867
public
static
class
OrganizationCalendar
extends
BaseCalendar {
868
@
k
public
ExternalOrganization organization;
869
@_backLink(
"forResource"
)
870
@_displayInline
871
@_subPropertyOf(
"available"
)
872
@s
public
Available[] open;
873
@_backLink(
"forResource"
)
874
@_displayInline
875
@_subPropertyOf(
"unavailable"
)
876
@s
public
Unavailable[] closed;
877
@h@s
public
String name;
878
}
879
880
@DavClass._largeIcon(
"icons/classes/CalendarItem-large.gif"
)
881
@DavClass._icon(
"icons/classes/CalendarItem.gif"
)
882
@DavClass._cachable
883
public
static
class
CalendarItem
implements
RecurrentItem {
884
@
k
public
Integer seq;
885
@
k
public
BaseCalendar forResource;
886
@_sortAscending(
false
)
887
@_readOnly
888
@_onCreate
889
public
dateTime created = writeJS(
"created ? created : new Date().getTime()"
);
890
@_displayNameElm
891
public
String notes;
892
@_abstract
893
@c
public
ComplexDate start;
//* at what date/time event should start
894
@_abstract
895
@_cloneOf(
"end"
)
896
@c
public
ComplexDate finish;
//* at what date/time event should end
897
@c
public
Frequency frequency;
//* defines the recurrent pattern
898
@c
public
Long repeatFrom;
//* marks that this event should not start repeating until this date
899
@c
public
Long repeatUntil;
//* marks that this event should not stop repeating after this date
900
@h@c
public
Integer maxRepetitions;
//* marks that this event should stop repeating after this many iterations
901
@
r
@c
public
Duration duration;
//* duration of the event
902
@_sortAscending
903
public
CalendarItemType busyOrAvailable;
904
}
905
906
public
static
enum CalendarItemType {
907
Available, Busy;
908
}
909
910
@DavClass._aView
911
@DavClass._largeIcon(
"icons/classes/Available-large.gif"
)
912
@DavClass._icon(
"icons/classes/Available.gif"
)
913
@DavClass._where(
"busyOrAvailable == 'Available'"
)
914
@DavClass._filterView
915
public
static
class
Available
extends
CalendarItem {
916
@
k
@s
public
Integer seq;
917
@
k
@s
public
BaseCalendar forResource;
918
@_readOnly
919
@_onCreate
920
@s
public
dateTime created;
921
@_displayNameElm
922
@s
public
String notes;
923
@_abstract
924
@s
public
ComplexDate start;
925
@_abstract
926
@s
public
ComplexDate finish;
927
@s
public
Frequency frequency;
928
@s
public
dateTime repeatFrom;
929
@s
public
dateTime repeatUntil;
930
@h@s
public
Integer maxRepetitions;
931
@
r
@s
public
Duration duration;
932
@_readOnly
933
@_onCreate
934
@s
public
CalendarItemType busyOrAvailable = writeJS(
"'Available'"
);
935
}
936
937
@DavClass._aView
938
@DavClass._largeIcon(
"icons/classes/Busy-large.gif"
)
939
@DavClass._icon(
"icons/classes/Busy.gif"
)
940
@DavClass._where(
"busyOrAvailable == 'Busy'"
)
941
@DavClass._filterView
942
public
static
class
Unavailable
extends
CalendarItem {
943
@
k
@s
public
Integer seq;
944
@
k
@s
public
BaseCalendar forResource;
945
@_readOnly
946
@_onCreate
947
@s
public
dateTime created;
948
@_displayNameElm
949
@s
public
String notes;
950
@_abstract
951
@s
public
ComplexDate start;
952
@_abstract
953
@s
public
ComplexDate finish;
954
@s
public
Frequency frequency;
955
@s
public
dateTime repeatFrom;
956
@s
public
dateTime repeatUntil;
957
@h@s
public
Integer maxRepetitions;
958
@
r
@s
public
Duration duration;
959
@_readOnly
960
@_onCreate
961
@s
public
CalendarItemType busyOrAvailable = writeJS(
"'Busy'"
);
962
}
963
964
/**
965
* Project interdependencies are arguably the most important part of project management.
966
*/
967
@DavClass._largeIcon(
"icons/classes/Codependency-large.gif"
)
968
@DavClass._viewColsNumber(
9
)
969
@DavClass._icon(
"icons/classes/Codependency.gif"
)
970
public
static
class
TaskDependency
implements
FolderItem {
971
@_cloneOf(
"rootFolder"
)
972
@c
public
Project project;
973
@_cloneOf(
"folder"
)
974
@
k
@c
public
Task from;
975
@_icon(
"icons/start.gif"
)
976
public
ComplexDate fromStart = formula(
"from.start"
);
977
@_icon(
"icons/end.gif"
)
978
public
ComplexDate fromFinish = formula(
"from.finish"
);
979
@
k
public
Task to;
980
@_icon(
"icons/actualStart.gif"
)
981
public
ComplexDate toStart = formula(
"from.start"
);
982
@_icon(
"icons/actualEnd.gif"
)
983
public
ComplexDate toFinish = formula(
"from.finish"
);
984
@_maxSize(
2000
)
985
public
String description;
//* describe the assumptions made, the risk involved and the possibility for resolving a dependency
986
@_onCreate
987
public
DependencyType dependencyType = writeJS(
"(dependencyType == null) ? 'FINISH_START' : dependencyType"
);
988
}
989
990
public
static
enum DependencyType {
991
FINISH_START, START_FINISH, START_START, FINISH_FINISH;
992
}
993
994
public
static
class
WorkOrderCompletion {
995
@
k
public
WorkOrder order;
996
@
k
public
Integer seq;
997
@_maxSize(
100
)
998
@
r
public
String name;
999
@_maxSize(
1000
)
1000
public
String description;
1001
public
ComplexDate dateCompleted;
1002
}
1003
1004
/**
1005
* Defines items that will be delivered/provided to a customer
1006
*/
1007
public
static
class
Deliverable
extends
WorkOrderCompletion {
1008
@
k
@s
public
WorkOrder order;
1009
@
k
@s
public
Integer seq;
1010
}
1011
1012
/**
1013
* Defines items that will be delivered/provided internally
1014
*/
1015
public
static
class
InternalDeliverable
extends
WorkOrderCompletion {
1016
@
k
@s
public
WorkOrder order;
1017
@
k
@s
public
Integer seq;
1018
}
1019
1020
/**
1021
* Tracks the completion of the task
1022
*/
1023
public
static
class
TaskCompletion {
1024
@
k
public
Task task;
1025
public
WorkItem workItem;
// :: order;
1026
public
ComplexDate dateCompleted;
1027
}
1028
1029
/**
1030
* Rates for a specific position
1031
*/
1032
public
static
class
PositionRate
extends
hudsonfog.voc.model.humanResources.PositionRate
{
1033
@_displayNameElm
1034
@
k
@s
public
Position position;
1035
@_displayNameElm
1036
@
k
@s
public
RateType rateType;
1037
@
k
@s
public
PayPeriod payPeriod;
1038
@
k
@s
public
Long fromDate;
1039
}
1040
1041
public
static
enum RateType {
1042
@_label(
"Regular billing"
) RegularBilling, @_label(
"Overtime billing"
) OvertimeBilling, @_label(
"Regular pay"
) RegularPay, @_label(
"Overtime pay"
) OvertimePay;
1043
}
1044
1045
/**
1046
* Rates of a specific person
1047
*/
1048
public
static
class
PartyRate {
1049
@
k
public
Contact contact;
1050
@
k
public
Long fromDate;
1051
public
Long thruDate;
1052
public
RateType rateType;
1053
}
1054
1055
/**
1056
* Rates used for a particular work effort assignment
1057
*/
1058
public
static
class
AssignmentRate {
1059
@
k
public
WorkAssignment workAssignment;
1060
@
k
public
Long fromDate;
1061
public
Long thruDate;
1062
public
RateType rateType;
1063
}
1064
1065
/**
1066
* Rate card is a way to group position rates and assign it a name, status, etc.
1067
*/
1068
public
static
class
RateCard
implements
Templatable {
1069
@
k
public
ExternalOrganization organization;
//* rate cards within a specific organization
1070
@_maxSize(
25
)
1071
@_displayNameElm
1072
@
k
public
String cardName;
//* all rate cards have a name
1073
@_backLink(
"rateCard"
)
1074
@_displayInline
1075
public
Rate[] rates;
//* rates in this card
1076
@_where(
"active == true"
)
1077
@_immutable
1078
@_cloneOf(
"basedOnTemplate"
)
1079
@_onCreate
1080
@c
public
RateCard basedOnRateCard;
//* the original template resource
1081
@_cloneOf(
"isTemplate"
)
1082
@c
public
Boolean active;
//* allows to mark this Project as a template
1083
}
1084
1085
/**
1086
* Rate on a rate card.
1087
*/
1088
public
static
class
Rate {
1089
@_displayNameElm
1090
@
k
public
RateCard rateCard;
1091
@
k
public
Integer seq;
1092
@_displayNameElm
1093
public
Position position;
1094
public
Money hourlyRate;
1095
}
1096
1097
/**
1098
* Estimated work & its cost
1099
*/
1100
public
static
class
WorkBudget
extends
RateCard {
1101
@
k
public
Project project;
1102
@h@s
public
ExternalOrganization organization;
1103
@_displayNameElm
1104
@_subPropertyOf(
"cardName"
)
1105
@h@s
public
String budgetRevisionName;
1106
@_backLink(
"budget"
)
1107
@_displayInline
1108
@_subPropertyOf(
"rates"
)
1109
@s
public
WorkBudgetItem[] budgetItems;
1110
@s
public
RateCard basedOnRateCard;
//* the original template resource
1111
@h@s
public
Boolean active;
1112
@_icon(
"icons/classes/Money.gif"
)
1113
@_readOnly
1114
@_makeTotal
1115
public
Money cost = writeJS(
"getThisChange().cost ? cost: getThisChange().budgetItems ? budgetItems.SUM('cost') : cost"
);
1116
@_makeTotal
1117
@_readOnly
1118
@_icon(
"icons/classes/WorkEffort.gif"
)
1119
public
Duration work = writeJS(
"getThisChange().work ? work: getThisChange().budgetItems ? budgetItems.SUM('work') : work"
);
1120
}
1121
1122
/**
1123
* Estimated work for a specific role & its cost
1124
*/
1125
@DavClass._