1 56 57 package org.opencrx.kernel.layer.application; 58 59 import java.io.ByteArrayOutputStream ; 60 import java.io.PrintWriter ; 61 import java.math.BigDecimal ; 62 import java.text.ParseException ; 63 import java.util.ArrayList ; 64 import java.util.Collections ; 65 import java.util.Date ; 66 import java.util.GregorianCalendar ; 67 import java.util.HashSet ; 68 import java.util.Iterator ; 69 import java.util.List ; 70 import java.util.Locale ; 71 import java.util.Set ; 72 73 import org.opencrx.kernel.generic.OpenCrxException; 74 import org.openmdx.base.accessor.jmi.cci.RefPackage_1_0; 75 import org.openmdx.base.exception.ServiceException; 76 import org.openmdx.base.text.format.DateFormat; 77 import org.openmdx.compatibility.base.dataprovider.cci.AttributeSelectors; 78 import org.openmdx.compatibility.base.dataprovider.cci.DataproviderObject; 79 import org.openmdx.compatibility.base.dataprovider.cci.DataproviderObject_1_0; 80 import org.openmdx.compatibility.base.dataprovider.cci.Directions; 81 import org.openmdx.compatibility.base.dataprovider.cci.RequestCollection; 82 import org.openmdx.compatibility.base.dataprovider.cci.ServiceHeader; 83 import org.openmdx.compatibility.base.dataprovider.cci.SystemAttributes; 84 import org.openmdx.compatibility.base.naming.Path; 85 import org.openmdx.compatibility.base.query.FilterOperators; 86 import org.openmdx.compatibility.base.query.FilterProperty; 87 import org.openmdx.compatibility.base.query.Quantors; 88 import org.openmdx.kernel.exception.BasicException; 89 import org.openmdx.kernel.log.SysLog; 90 import org.openmdx.model1.accessor.basic.cci.Model_1_0; 91 92 public class Activities { 93 94 public Activities( 96 Model_1_0 model, 97 OpenCrxKernel_1 plugin, 98 RequestCollection delegation, 99 RefPackage_1_0 rootPkg 100 ) { 101 this.model = model; 102 this.plugin = plugin; 103 this.delegation = delegation; 104 this.rootPkg = rootPkg; 105 } 106 107 private int calculateOpenActivityTimeDistribution( 109 ServiceHeader header, 110 Path reference, 111 String objectClass, 112 int[] timeDistribution, 113 String distributionOnAttribute, 114 boolean lookAhead 115 ) { 116 try { 117 List activities = this.delegation.addFindRequest( 118 reference, 119 new FilterProperty[]{ 120 new FilterProperty( 121 Quantors.THERE_EXISTS, 122 SystemAttributes.OBJECT_CLASS, 123 FilterOperators.IS_IN, 124 new String []{objectClass} 125 ), 126 new FilterProperty( 127 Quantors.THERE_EXISTS, 128 "percentComplete", 129 FilterOperators.IS_LESS, 130 new Number []{new Short ((short)100)} 131 ) 132 }, 133 AttributeSelectors.ALL_ATTRIBUTES, 134 0, 135 Activities.BATCHING_MODE_SIZE, 136 Directions.ASCENDING 137 ); 138 139 int count = 0; 140 for( 141 Iterator i = activities.iterator(); 142 i.hasNext(); 143 ) { 144 DataproviderObject_1_0 activity = (DataproviderObject_1_0)i.next(); 145 Date dt = new Date (); 146 try { 147 dt = org.openmdx.base.text.format.DateFormat.getInstance().parse( 148 (String )activity.values(distributionOnAttribute).get(0) 149 ); 150 } catch(Exception e) {} 151 152 long delayInDays = (lookAhead ? 1 : -1) * (dt.getTime() - System.currentTimeMillis()) / 86400000; 153 if(delayInDays < 0) timeDistribution[0]++; 154 else if(delayInDays < 1) timeDistribution[1]++; 155 else if(delayInDays < 2) timeDistribution[2]++; 156 else if(delayInDays < 3) timeDistribution[3]++; 157 else if(delayInDays < 4) timeDistribution[4]++; 158 else if(delayInDays < 5) timeDistribution[5]++; 159 else if(delayInDays < 6) timeDistribution[6]++; 160 else if(delayInDays < 7) timeDistribution[7]++; 161 else if(delayInDays < 8) timeDistribution[8]++; 162 else if(delayInDays < 15) timeDistribution[9]++; 163 else if(delayInDays < 31) timeDistribution[10]++; 164 else if(delayInDays < 91) timeDistribution[11]++; 165 else if(delayInDays < 181) timeDistribution[12]++; 166 else if(delayInDays < 361) timeDistribution[13]++; 167 else timeDistribution[14]++; 168 169 count++; 170 } 171 return count; 172 } 173 catch(ServiceException e) { 174 return 0; 175 } 176 } 177 178 DataproviderObject[] calculateUserHomeCharts( 180 ServiceHeader header, 181 Path userHome, 182 Path chartReference 183 ) throws ServiceException { 184 185 java.text.DateFormat dateFormat = 186 java.text.DateFormat.getDateInstance(java.text.DateFormat.SHORT, new Locale ("en_US")); 187 java.text.DateFormat timeFormat = 188 java.text.DateFormat.getTimeInstance(java.text.DateFormat.SHORT, new Locale ("en_US")); 189 String createdAt = dateFormat.format(new Date ()) + " " + timeFormat.format(new Date ()); 190 String fullName = ""; 192 try { 193 fullName = (String )this.plugin.retrieveObjectFromLocal( 194 header, 195 (Path)this.plugin.retrieveObjectFromLocal(header, userHome).values("contact").get(0) 196 ).values("fullName").get(0); 197 } catch(Exception e) {} 198 199 DataproviderObject[] charts = new DataproviderObject[2]; 200 String chartTitle = null; 201 202 205 chartTitle = (fullName.length() == 0 ? "" : fullName + ": ") + "Assigned Open Activities Overview (" + createdAt + ")"; 206 207 charts[0] = new DataproviderObject( 208 chartReference.getChild("2") 209 ); 210 charts[0].values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:home1:Chart"); 211 charts[0].values("description").add(chartTitle); 212 ByteArrayOutputStream os = new ByteArrayOutputStream (); 213 PrintWriter pw = new PrintWriter (os); 214 215 pw.println("BEGIN:VND.OPENDMDX-CHART"); 216 pw.println("VERSION:1.0"); 217 pw.println("COUNT:1"); 218 219 pw.println("CHART[0].TYPE:HORIZBAR"); 220 pw.println("CHART[0].LABEL:" + chartTitle); 221 pw.println("CHART[0].SCALEXTITLE:#Activities"); 222 pw.println("CHART[0].SCALEYTITLE:Activity type"); 223 pw.println("CHART[0].COUNT:" + ACTIVITY_TYPES.length); 224 225 int[] counts = new int[ACTIVITY_TYPES.length]; 226 int[] timeDistribution = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 227 Path assignedActivityReference = userHome.getChild("assignedActivity"); 228 for( 229 int i = 0; 230 i < ACTIVITY_TYPES.length; 231 i++ 232 ) { 233 String activityTypeName = (String )this.plugin.getCodes().getLongText( 234 CODEVALUENAME_ACTIVITY_TYPE, 235 (short)0, 236 true 237 ).get(new Short ((short)i)); 238 pw.println("CHART[0].LABEL[" + i + "]:" + activityTypeName); 239 counts[i] = 240 this.calculateOpenActivityTimeDistribution( 241 header, 242 assignedActivityReference, 243 ACTIVITY_TYPES[i], 244 timeDistribution, 245 "scheduledStart", 246 true 247 ); 248 } 249 int maxValue = 0; 250 for(int i = 0; i < counts.length; i++) { 251 pw.println("CHART[0].VAL[" + i + "]:" + counts[i]); 252 pw.println("CHART[0].BORDER[" + i + "]:#000066"); 253 pw.println("CHART[0].FILL[" + i + "]:#F6D66D"); 254 maxValue = Math.max(maxValue, counts[i]); 255 } 256 pw.println("CHART[0].MINVALUE:0"); 257 pw.println("CHART[0].MAXVALUE:" + maxValue); 258 pw.println("END:VND.OPENDMDX-CHART"); 259 try { 260 pw.flush(); 261 os.close(); 262 } catch(Exception e) {} 263 charts[0].values("chart").add( 264 os.toByteArray() 265 ); 266 charts[0].values("chartMimeType").add("application/vnd.openmdx-chart"); 267 charts[0].values("chartName").add( 268 this.plugin.toFilename(chartTitle + ".txt") 269 ); 270 271 274 chartTitle = (fullName.length() == 0 ? "" : fullName + ": ") + "Assigned Open Activities Age Distribution (" + createdAt + ")"; 275 276 charts[1] = new DataproviderObject( 277 chartReference.getChild("3") 278 ); 279 charts[1].values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:home1:Chart"); 280 charts[1].values("description").add(chartTitle); 281 os = new ByteArrayOutputStream (); 282 pw = new PrintWriter (os); 283 284 pw.println("BEGIN:VND.OPENDMDX-CHART"); 285 pw.println("VERSION:1.0"); 286 pw.println("COUNT:1"); 287 288 pw.println("CHART[0].TYPE:VERTBAR"); 289 pw.println("CHART[0].LABEL:" + chartTitle); 290 pw.println("CHART[0].SCALEXTITLE:#Days"); 291 pw.println("CHART[0].SCALEYTITLE:#Activities"); 292 pw.println("CHART[0].COUNT:15"); 293 294 pw.println("CHART[0].LABEL[0]:past due"); 295 pw.println("CHART[0].LABEL[1]:today"); 296 pw.println("CHART[0].LABEL[2]:1"); 297 pw.println("CHART[0].LABEL[3]:2"); 298 pw.println("CHART[0].LABEL[4]:3"); 299 pw.println("CHART[0].LABEL[5]:4"); 300 pw.println("CHART[0].LABEL[6]:5"); 301 pw.println("CHART[0].LABEL[7]:6"); 302 pw.println("CHART[0].LABEL[8]:7"); 303 pw.println("CHART[0].LABEL[9]:..14"); 304 pw.println("CHART[0].LABEL[10]:..30"); 305 pw.println("CHART[0].LABEL[11]:..90"); 306 pw.println("CHART[0].LABEL[12]:..180"); 307 pw.println("CHART[0].LABEL[13]:..360"); 308 pw.println("CHART[0].LABEL[14]:>360 days"); 309 310 maxValue = 0; 311 for(int i = 0; i < 15; i++) { 312 pw.println("CHART[0].VAL[" + i + "]:" + timeDistribution[i]); 313 pw.println("CHART[0].BORDER[" + i + "]:#000066"); 314 pw.println("CHART[0].FILL[" + i + "]:#F6D66D"); 315 maxValue = Math.max(maxValue, timeDistribution[i]); 316 } 317 318 pw.println("CHART[0].MINVALUE:0"); 319 pw.println("CHART[0].MAXVALUE:" + maxValue); 320 321 pw.println("END:VND.OPENDMDX-CHART"); 322 323 try { 324 pw.flush(); 325 os.close(); 326 } catch(Exception e) {} 327 charts[1].values("chart").add( 328 os.toByteArray() 329 ); 330 charts[1].values("chartMimeType").add("application/vnd.openmdx-chart"); 331 charts[1].values("chartName").add( 332 this.plugin.toFilename(chartTitle + ".txt") 333 ); 334 335 return charts; 336 } 337 338 public DataproviderObject refreshTracker( 340 ServiceHeader header, 341 DataproviderObject_1_0 activityTracker 342 ) throws ServiceException { 343 DataproviderObject refreshedTracker = this.plugin.retrieveObjectForModification(activityTracker.path()); 344 345 List activites = this.delegation.addFindRequest( 346 activityTracker.path().getChild("filteredActivity"), 347 null, 348 AttributeSelectors.NO_ATTRIBUTES, 349 0, 350 BATCHING_MODE_SIZE, 351 Directions.ASCENDING 352 ); 353 int estimateEffortHours = 0; 354 int estimateEffortMinutes = 0; 355 for( 358 Iterator i = activites.iterator(); 359 i.hasNext(); 360 ) { 361 DataproviderObject_1_0 activity = (DataproviderObject_1_0)i.next(); 362 List effortEstimates = this.delegation.addFindRequest( 363 new Path((String )activity.values(SystemAttributes.OBJECT_IDENTITY).get(0)).getChild("effortEstimate"), 364 null, 365 AttributeSelectors.ALL_ATTRIBUTES, 366 0, 367 Integer.MAX_VALUE, 368 Directions.ASCENDING 369 ); 370 if(effortEstimates.size() == 1) { 371 DataproviderObject_1_0 effortEstimate = (DataproviderObject_1_0)effortEstimates.iterator().next(); 372 if(effortEstimate.values("estimateEffortHours").size() > 0) { 373 estimateEffortHours += ((Number )effortEstimate.values("estimateEffortHours").get(0)).intValue(); 374 } 375 if(effortEstimate.values("estimateEffortMinutes").size() > 0) { 376 estimateEffortMinutes += ((Number )effortEstimate.values("estimateEffortMinutes").get(0)).intValue(); 377 } 378 } 379 else { 381 for( 382 Iterator j = effortEstimates.iterator(); 383 j.hasNext(); 384 ) { 385 DataproviderObject_1_0 effortEstimate = (DataproviderObject_1_0)j.next(); 386 if( 387 (effortEstimate.values("isMain").size() > 0) && 388 ((Boolean )effortEstimate.values("isMain").get(0)).booleanValue() 389 ) { 390 if(effortEstimate.values("estimateEffortHours").size() > 0) { 391 estimateEffortHours += ((Number )effortEstimate.values("estimateEffortHours").get(0)).intValue(); 392 } 393 if(effortEstimate.values("estimateEffortMinutes").size() > 0) { 394 estimateEffortMinutes += ((Number )effortEstimate.values("estimateEffortMinutes").get(0)).intValue(); 395 } 396 } 397 } 398 } 399 } 400 refreshedTracker.clearValues("sumEstimateEffortHours").add( 402 new Integer (estimateEffortHours + estimateEffortMinutes / 60) 403 ); 404 refreshedTracker.clearValues("sumEstimateEffortMinutes").add( 405 new Integer (estimateEffortMinutes % 60) 406 ); 407 return refreshedTracker; 408 } 409 410 414 public Path newActivity( 415 ServiceHeader header, 416 Path activityCreatorIdentity, 417 String name, 418 String description, 419 String detailedDescription, 420 String suppliedScheduledStart, 421 String suppliedScheduledEnd, 422 String suppliedDueBy, 423 Number suppliedPriority, 424 Path reportingContactIdentity 425 ) throws ServiceException { 426 DataproviderObject_1_0 activityCreator = this.plugin.retrieveObjectFromDelegation( 427 activityCreatorIdentity 428 ); 429 if(activityCreator.values("activityType").size() > 0) { 430 DataproviderObject_1_0 activityType = this.plugin.retrieveObjectFromDelegation( 431 (Path)activityCreator.values("activityType").get(0) 432 ); 433 DataproviderObject_1_0 activityProcess = this.plugin.retrieveObjectFromDelegation( 434 (Path)activityType.values("controlledBy").get(0) 435 ); 436 String scheduledStart = null; 437 try { 438 scheduledStart = suppliedScheduledStart != null 439 ? suppliedScheduledStart 440 : (activityCreator.values("baseDate").size() > 0) && (activityCreator.values("scheduledStart").size() > 0) 441 ? DateFormat.getInstance().format(new Date (System.currentTimeMillis() + (DateFormat.getInstance().parse((String )activityCreator.values("scheduledStart").get(0)).getTime() - DateFormat.getInstance().parse((String )activityCreator.values("baseDate").get(0)).getTime()))) 442 : null; 443 } catch(ParseException e) {} 444 String scheduledEnd = null; 445 try { 446 scheduledEnd = suppliedScheduledEnd != null 447 ? suppliedScheduledEnd 448 : (activityCreator.values("baseDate").size() > 0) && (activityCreator.values("scheduledEnd").size() > 0) 449 ? DateFormat.getInstance().format(new Date (System.currentTimeMillis() + (DateFormat.getInstance().parse((String )activityCreator.values("scheduledEnd").get(0)).getTime() - DateFormat.getInstance().parse((String )activityCreator.values("baseDate").get(0)).getTime()))) 450 : null; 451 } catch(ParseException e) {} 452 String dueBy = null; 453 try { 454 dueBy = suppliedDueBy != null 455 ? suppliedDueBy 456 : (activityCreator.values("baseDate").size() > 0) && (activityCreator.values("dueBy").size() > 0) 457 ? DateFormat.getInstance().format(new Date (System.currentTimeMillis() + (DateFormat.getInstance().parse((String )activityCreator.values("dueBy").get(0)).getTime() - DateFormat.getInstance().parse((String )activityCreator.values("baseDate").get(0)).getTime()))) 458 : null; 459 } catch(ParseException e) {} 460 short priority = suppliedPriority != null 461 ? suppliedPriority.shortValue() 462 : activityCreator.values("priority").size() > 0 463 ? ((Number )activityCreator.values("priority").get(0)).shortValue() 464 : (short)2; Path newActivityIdentity = new Path("xri:@openmdx:org.opencrx.kernel.activity1/provider"); 466 newActivityIdentity = 467 newActivityIdentity.getDescendant( 468 new String []{ 469 activityCreator.path().get(2), 470 "segment", 471 activityCreator.path().get(4), 472 "activity", 473 this.plugin.getUidAsString() 474 } 475 ); 476 DataproviderObject newActivity = new DataproviderObject(newActivityIdentity); 477 String activityClass = ACTIVITY_TYPES[((Number )activityType.values("activityClass").get(0)).intValue()]; 478 newActivity.values(SystemAttributes.OBJECT_CLASS).add(activityClass); 479 if(name != null) { 480 newActivity.values("name").add(name); 481 } 482 if(description != null) { 483 newActivity.values("description").add(description); 484 } 485 if(detailedDescription != null) { 486 newActivity.values("detailedDescription").add(detailedDescription); 487 } 488 if(scheduledStart != null) { 489 newActivity.values("scheduledStart").add(scheduledStart); 490 } 491 if(scheduledEnd != null) { 492 newActivity.values("scheduledEnd").add(scheduledEnd); 493 } 494 if(reportingContactIdentity != null) { 495 newActivity.values("reportingContact").add(reportingContactIdentity); 496 } 497 else { 498 DataproviderObject_1_0 userHome = this.plugin.getUserHome(header, newActivity.path()); 499 newActivity.values("reportingContact").addAll( 500 userHome.values("contact") 501 ); 502 } 503 newActivity.values("priority").add( 504 new Short (priority) 505 ); 506 newActivity.values("dueBy").add( 507 dueBy != null 508 ? dueBy 509 : MAX_DATE 510 ); 511 newActivity.values("activityState").add( 512 new Short ((short)0) 513 ); 514 newActivity.values("percentComplete").add( 515 new Short ((short)0) 516 ); 517 newActivity.values("activityType").add( 518 activityType.path() 519 ); 520 newActivity.values("processState").addAll( 521 activityProcess.values("startState") 522 ); 523 if("org:opencrx:kernel:activity1:Incident".equals(activityClass)) { 525 newActivity.values("caseOrigin").add(new Short ((short)0)); 526 newActivity.values("caseType").add(new Short ((short)0)); 527 newActivity.values("customerSatisfaction").add(new Short ((short)0)); 528 newActivity.values("severity").add(new Short ((short)0)); 529 newActivity.values("reproducibility").add(new Short ((short)0)); 530 } 531 try { 532 this.plugin.createObject( 534 newActivity 535 ); 536 this.reapplyActivityCreator( 537 header, 538 newActivity.path(), 539 activityCreator.path() 540 ); 541 return newActivityIdentity; 542 } 543 catch(ServiceException e) { 544 SysLog.info("Creation of new activity failed", e.getCause(), 1); 545 } 546 } 547 return null; 548 } 549 550 public Path voteForActivity( 552 ServiceHeader header, 553 DataproviderObject_1_0 activity, 554 DataproviderObject params 555 ) throws ServiceException { 556 DataproviderObject vote = new DataproviderObject( 557 activity.path().getDescendant(new String []{"vote", this.plugin.getUidAsString()}) 558 ); 559 vote.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:activity1:ActivityVote"); 560 String name = (String )params.values("name").get(0); 561 String description = (String )params.values("description").get(0); 562 if(name != null) { 563 vote.values("name").add(name); 564 } 565 if(description != null) { 566 vote.values("description").add(description); 567 } 568 this.plugin.assignToMe( 569 header, 570 vote, 571 null, 572 true, 573 null 574 ); 575 this.plugin.createObject(vote); 576 return vote.path(); 577 } 578 579 public void doFollowUp( 581 ServiceHeader header, 582 Path activityIdentity, 583 String followUpTitle, 584 String followUpText, 585 Path processTransitionIdentity 586 ) throws ServiceException { 587 588 DataproviderObject_1_0 activity = this.plugin.retrieveObjectForModification(activityIdentity); 589 Path processStateIdentity = (Path)activity.values("processState").get(0); 590 if(processTransitionIdentity != null) { 591 DataproviderObject_1_0 processTransition = this.plugin.retrieveObjectFromDelegation( 592 processTransitionIdentity 593 ); 594 if(processTransition.values("nextState").size() == 0) { 595 throw new ServiceException( 596 OpenCrxException.DOMAIN, 597 OpenCrxException.ACTIVITY_UNDEFINED_NEXT_STATE, 598 new BasicException.Parameter[]{ 599 new BasicException.Parameter("param0", processTransition.path()) 600 }, 601 "Undefined next state. Transition not possible." 602 ); 603 } 604 if( 606 ((processTransition.values("prevState").size() == 0) && (processStateIdentity == null)) || 607 ((processTransition.values("prevState").size() > 0) && processTransition.values("prevState").get(0).equals(processStateIdentity)) 608 ) { 609 610 } 611 else { 612 throw new ServiceException( 613 OpenCrxException.DOMAIN, 614 OpenCrxException.ACTIVITY_TRANSITION_NOT_VALID_FOR_STATE, 615 new BasicException.Parameter[]{ 616 new BasicException.Parameter("param0", processTransitionIdentity), 617 new BasicException.Parameter("param1", processStateIdentity) 618 }, 619 "Transition is not valid for current state" 620 ); 621 } 622 activity.clearValues("processState").add( 624 processTransition.values("nextState").get(0) 625 ); 626 activity.clearValues("lastTransition").add( 627 processTransitionIdentity 628 ); 629 activity.clearValues("percentComplete").addAll( 630 processTransition.values("newPercentComplete") 631 ); 632 activity.clearValues("activityState").addAll( 633 processTransition.values("newActivityState") 634 ); 635 636 List actions = this.delegation.addFindRequest( 638 processTransitionIdentity.getChild("action"), 639 null, 640 AttributeSelectors.ALL_ATTRIBUTES, 641 0, 642 Integer.MAX_VALUE, 643 Directions.ASCENDING 644 ); 645 for(Iterator i = actions.iterator(); i.hasNext(); ) { 646 DataproviderObject_1_0 action = (DataproviderObject_1_0)i.next(); 647 String actionClass = (String )action.values(SystemAttributes.OBJECT_CLASS).get(0); 648 if(this.model.isSubtypeOf(actionClass, "org:opencrx:kernel:activity1:SetActualEndAction")) { 650 if((action.values("resetToNull").size() > 0) && ((Boolean )action.values("resetToNull").get(0)).booleanValue()) { 651 activity.clearValues("actualEnd"); 652 } 653 else { 654 activity.clearValues("actualEnd").add( 655 DateFormat.getInstance().format(new Date ()) 656 ); 657 } 658 } 659 else if(this.model.isSubtypeOf(actionClass, "org:opencrx:kernel:activity1:SetActualStartAction")) { 661 if((action.values("resetToNull").size() > 0) && ((Boolean )action.values("resetToNull").get(0)).booleanValue()) { 662 activity.clearValues("actualStart"); 663 } 664 else { 665 activity.clearValues("actualStart").add( 666 DateFormat.getInstance().format(new Date ()) 667 ); 668 } 669 } 670 else if(this.model.isSubtypeOf(actionClass, "org:opencrx:kernel:activity1:SetAssignedToAction")) { 672 List assignedResources = this.delegation.addFindRequest( 673 activityIdentity.getChild("assignedResource"), 674 null, 675 AttributeSelectors.ALL_ATTRIBUTES, 676 0, 677 Integer.MAX_VALUE, 678 Directions.ASCENDING 679 ); 680 boolean assigned = false; 681 Path contactIdentity = null; 683 if( 684 (action.values("contactFeatureName").size() > 0) && 685 (activity.values((String )action.values("contactFeatureName").get(0)).size() > 0) 686 ) { 687 contactIdentity = (Path)activity.values((String )action.values("contactFeatureName").get(0)).get(0); 688 } 689 else { 690 DataproviderObject_1_0 userHome = this.plugin.getUserHome(header, action.path()); 691 contactIdentity = (Path)userHome.values("contact").get(0); 692 } 693 if(contactIdentity != null) { 694 for(Iterator j = assignedResources.iterator(); j.hasNext(); ) { 695 DataproviderObject_1_0 assignedResource = (DataproviderObject_1_0)j.next(); 696 if(assignedResource.values("resource").size() > 0) { 697 DataproviderObject_1_0 resource = this.plugin.retrieveObjectFromDelegation( 698 (Path)assignedResource.values("resource").get(0) 699 ); 700 if( 701 (resource.values("contact").size() > 0) && 702 contactIdentity.equals(resource.values("contact").get(0)) 703 ) { 704 this.assignTo( 705 header, 706 activityIdentity, 707 resource.path() 708 ); 709 assigned = true; 710 break; 711 } 712 } 713 } 714 } 715 if( 717 !assigned && 718 (action.values("resourceOrder").size() > 0) 719 ) { 720 for(Iterator j = assignedResources.iterator(); j.hasNext(); ) { 721 DataproviderObject_1_0 assignedResource = (DataproviderObject_1_0)j.next(); 722 if(assignedResource.values("resourceOrder").size() > 0) { 723 short actionResourceOrder = ((Number )action.values("resourceOrder").get(0)).shortValue(); 724 short assignmentResourceOrder = ((Number )assignedResource.values("resourceOrder").get(0)).shortValue(); 725 if( 726 (actionResourceOrder == assignmentResourceOrder) && 727 (assignedResource.values("resource").size() > 0) 728 ) { 729 this.assignTo( 730 header, 731 activityIdentity, 732 (Path)assignedResource.values("resource").get(0) 733 ); 734 assigned = true; 735 break; 736 } 737 } 738 } 739 } 740 if( 742 !assigned && 743 (action.values("resourceRole").size() > 0) 744 ) { 745 for(Iterator j = assignedResources.iterator(); j.hasNext(); ) { 746 DataproviderObject_1_0 assignedResource = (DataproviderObject_1_0)j.next(); 747 if(assignedResource.values("resourceRole").size() > 0) { 748 short actionResourceRole = ((Number )action.values("resourceRole").get(0)).shortValue(); 749 short assignmentResourceRole = ((Number )assignedResource.values("resourceRole").get(0)).shortValue(); 750 if( 751 (actionResourceRole == assignmentResourceRole) && 752 (assignedResource.values("resource").size() > 0) 753 ) { 754 this.assignTo( 755 header, 756 activityIdentity, 757 (Path)assignedResource.values("resource").get(0) 758 ); 759 assigned = true; 760 break; 761 } 762 } 763 } 764 } 765 } 766 else if(this.model.isSubtypeOf(actionClass, "org:opencrx:kernel:activity1:WfAction")) { 768 DataproviderObject_1_0 userHome = this.plugin.getUserHome(header, action.path()); 769 if(action.values("wfProcess").size() > 0) { 770 this.plugin.workflows.executeWorkflow( 771 userHome, 772 (Path)action.values("wfProcess").get(0), 773 activityIdentity, 774 null, 775 null, 776 null, 777 null 778 ); 779 } 780 } 781 else if(this.model.isSubtypeOf(actionClass, "org:opencrx:kernel:activity1:ActivityCreationAction")) { 783 if(action.values("activityCreator").size() > 0) { 784 Path newActivityIdentity = this.newActivity( 785 header, 786 (Path)action.values("activityCreator").get(0), 787 (String )action.values("activityName").get(0), 788 (String )action.values("activityDescription").get(0), 789 null, 790 null, 791 null, 792 null, 793 null, 794 (Path)activity.values("reportingContact").get(0) 795 ); 796 DataproviderObject activityLinkTo = new DataproviderObject( 798 newActivityIdentity.getDescendant(new String []{"activityLinkTo", this.plugin.getUidAsString()}) 799 ); 800 activityLinkTo.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:activity1:ActivityLinkTo"); 801 activityLinkTo.values("name").addAll( 802 activity.values("name") 803 ); 804 activityLinkTo.values("activityLinkType").add( 805 new Short (ACTIVITY_LINK_TYPE_IS_DERIVED_FROM) 806 ); 807 activityLinkTo.values("linkTo").add(activityIdentity); 808 this.plugin.createObject( 809 activityLinkTo 810 ); 811 if(this.model.isSubtypeOf(actionClass, "org:opencrx:kernel:activity1:EMailCreationAction")) { 813 DataproviderObject emailActivity = this.plugin.retrieveObjectForModification( 814 newActivityIdentity 815 ); 816 String emailActivityClass = (String )emailActivity.values(SystemAttributes.OBJECT_CLASS).get(0); 817 if(this.model.isSubtypeOf(emailActivityClass, "org:opencrx:kernel:activity1:EMail")) { 818 List recipients = this.delegation.addFindRequest( 820 activityIdentity.getChild("emailRecipient"), 821 null, 822 AttributeSelectors.ALL_ATTRIBUTES, 823 0, 824 Integer.MAX_VALUE, 825 Directions.ASCENDING 826 ); 827 for( 828 Iterator j = recipients.iterator(); 829 j.hasNext(); 830 ) { 831 DataproviderObject_1_0 recipient = (DataproviderObject_1_0)j.next(); 832 this.plugin.cloneable.cloneAndUpdateReferences( 833 header, 834 recipient, 835 newActivityIdentity.getChild("emailRecipient"), 836 null, 837 "", 838 true 839 ); 840 } 841 String messageSubject = 843 "" + emailActivity.values("name").get(0) + " " + activity.values("messageSubject").get(0); 844 emailActivity.clearValues("name").add(messageSubject); 845 emailActivity.clearValues("messageSubject").add(messageSubject); 846 emailActivity.clearValues("messageBody").add( 847 "" + emailActivity.values("description").get(0) + "\n" + activity.values("messageBody").get(0) 848 ); 849 emailActivity.clearValues("description"); 850 } 851 } 852 } 853 } 854 else if(this.model.isSubtypeOf(actionClass, "org:opencrx:kernel:activity1:LinkedActivityFollowUpAction")) { 856 List activityLinks = this.delegation.addFindRequest( 857 activityIdentity.getChild("activityLinkTo"), 858 null, 859 AttributeSelectors.ALL_ATTRIBUTES, 860 0, 861 Integer.MAX_VALUE, 862 Directions.ASCENDING 863 ); 864 for(Iterator j = activityLinks.iterator(); j.hasNext(); ) { 865 DataproviderObject_1_0 activityLink = (DataproviderObject_1_0)i.next(); 866 Number activityLinkType = (Number )activityLink.values("activityLinkType").get(0); 867 Number actionActivityLinkType = (Number )action.values("activityLinkType").get(0); 868 if( 869 (activityLink.values("linkTo").size() > 0) && 870 (action.values("transition").size() > 0) && 871 (actionActivityLinkType != null) && 872 (activityLinkType != null) && 873 (actionActivityLinkType.shortValue() == activityLinkType.shortValue()) 874 ) { 875 this.doFollowUp( 876 header, 877 (Path)activityLink.values("linkTo").get(0), 878 (String )action.values("transitionTitle").get(0), 879 (String )action.values("transitionText").get(0), 880 (Path)action.values("transition").get(0) 881 ); 882 } 883 } 884 } 885 } 886 } 887 888 DataproviderObject transition = new DataproviderObject( 890 activity.path().getDescendant(new String []{"followUp", this.plugin.getUidAsString()}) 891 ); 892 transition.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:activity1:ActivityFollowUp"); 893 transition.values("transition").add(processTransitionIdentity); 894 transition.values("title").add(followUpTitle); 895 transition.values("text").add(followUpText); 896 this.plugin.assignToMe( 897 header, 898 transition, 899 null, 900 true, 901 null 902 ); 903 this.plugin.createObject(transition); 904 } 905 906 public void updateWorkRecord( 908 ServiceHeader header, 909 DataproviderObject workRecord, 910 DataproviderObject_1_0 oldValues 911 ) throws ServiceException { 912 if(this.plugin.isActivityWorkRecord(workRecord)) { 913 DateFormat dateFormat = DateFormat.getInstance(); 914 String startedAt = workRecord.getValues("startedAt") != null 915 ? (String )workRecord.values("startedAt").get(0) 916 : (oldValues == null ? dateFormat.format(new Date ()) : (String )oldValues.values("startedAt").get(0)); 917 String endedAt = workRecord.getValues("endedAt") != null 918 ? (String )workRecord.values("endedAt").get(0) 919 : (oldValues == null ? dateFormat.format(new Date ()) : (String )oldValues.values("endedAt").get(0)); 920 Number durationHours = workRecord.getValues("durationHours") != null 921 ? (Number )workRecord.values("durationHours").get(0) 922 : (oldValues == null ? new Integer (0) : (Number )oldValues.values("durationHours").get(0)); 923 Number durationMinutes = workRecord.getValues("durationMinutes") != null 924 ? (Number )workRecord.values("durationMinutes").get(0) 925 : (oldValues == null ? new Integer (0) : (Number )oldValues.values("durationMinutes").get(0)); 926 Number pauseDurationHours = workRecord.getValues("pauseDurationHours") != null 927 ? (Number )workRecord.values("pauseDurationHours").get(0) 928 : (oldValues == null ? new Integer (0) : (Number )oldValues.values("pauseDurationHours").get(0)); 929 Number pauseDurationMinutes = workRecord.getValues("pauseDurationMinutes") != null 930 ? (Number )workRecord.values("pauseDurationMinutes").get(0) 931 : (oldValues == null ? new Integer (0) : (Number )oldValues.values("pauseDurationMinutes").get(0)); 932 durationHours = durationHours == null ? new Integer (0) : durationHours; 933 durationMinutes = durationMinutes == null ? new Integer (0) : durationMinutes; 934 pauseDurationHours = pauseDurationHours == null ? new Integer (0) : pauseDurationHours; 935 pauseDurationMinutes = pauseDurationMinutes == null ? new Integer (0) : pauseDurationMinutes; 936 937 int durationCalculationMode = workRecord.getValues("durationCalculationMode") != null 938 ? ((Number )workRecord.getValues("durationCalculationMode").get(0)).intValue() 939 : (oldValues == null ? DURATION_CALCULATION_MODE_CALC_DURATION : ((Number )oldValues.values("durationCalculationMode").get(0)).intValue()); 940 941 if(durationCalculationMode == DURATION_CALCULATION_MODE_CALC_DURATION) { 943 long duration = 0; 944 try { 945 duration = 946 dateFormat.parse(endedAt).getTime() - dateFormat.parse(startedAt).getTime() - 947 pauseDurationHours.longValue() * 3600000 - pauseDurationMinutes.longValue() * 60000; 948 durationHours = new Long (duration / 3600000); 949 durationMinutes = new Long ((duration % 3600000) / 60000); 950 workRecord.clearValues("durationHours").add(durationHours); 951 workRecord.clearValues("durationMinutes").add(durationMinutes); 952 } catch(ParseException e) {} 953 } 954 else { 956 long pauseDuration = 0; 957 try { 958 pauseDuration = 959 dateFormat.parse(endedAt).getTime() - dateFormat.parse(startedAt).getTime() - 960 durationHours.longValue() * 3600000 - durationMinutes.longValue() * 60000; 961 pauseDurationHours = new Long (pauseDuration / 3600000); 962 pauseDurationMinutes = new Long ((pauseDuration % 3600000) / 60000); 963 workRecord.clearValues("pauseDurationHours").add(pauseDurationHours); 964 workRecord.clearValues("pauseDurationMinutes").add(pauseDurationMinutes); 965 } catch(ParseException e) {} 966 } 967 DataproviderObject_1_0 resourceAssignment = this.plugin.retrieveObjectFromDelegation( 969 workRecord.path().getPrefix(workRecord.path().size() - 2) 970 ); 971 Number rateType = workRecord.getValues("rateType") != null 973 ? (Number )workRecord.values("rateType").get(0) 974 : (oldValues == null ? new Short (RATE_TYPE_NA): (Number )oldValues.values("rateType").get(0)); 975 workRecord.clearValues("rateType").add(rateType); 976 DataproviderObject_1_0 resource = null; 978 if(resourceAssignment.values("resource").size() > 0) { 979 resource = this.plugin.retrieveObjectFromDelegation( 980 (Path)resourceAssignment.values("resource").get(0) 981 ); 982 } 983 BigDecimal rate = null; 984 if((rateType == null) || (rateType.shortValue() == RATE_TYPE_NA)) { 985 rate = workRecord.getValues("rate") != null 986 ? (BigDecimal )workRecord.values("rate").get(0) 987 : (oldValues == null ? new BigDecimal (0) : (BigDecimal )oldValues.values("rate").get(0)); 988 } 989 else if(rateType.shortValue() == RATE_TYPE_STANDARD) { 990 rate = (BigDecimal )resource.values("standardRate").get(0); 991 } 992 else { 993 rate = (BigDecimal )resource.values("overtimeRate").get(0); 994 } 995 if(rate == null) { 996 rate = new BigDecimal (0); 997 } 998 boolean updateWorkCompoundBooking = 999 (oldValues == null) || 1000 (((Number )workRecord.values("durationHours").get(0)).intValue () != ((Number )oldValues.values("durationHours").get(0)).intValue()) || 1001 (((Number )workRecord.values("durationMinutes").get(0)).intValue() != ((Number )oldValues.values("durationMinutes").get(0)).intValue()); 1002 boolean updateBillableAmount = 1003 updateWorkCompoundBooking || 1004 (rateType.intValue () != ((Number )oldValues.values("rateType").get(0)).intValue()) || 1005 (oldValues.values("rate").size() == 0) || 1006 (rate.doubleValue() != ((Number )oldValues.values("rate").get(0)).doubleValue()); 1007 if(updateBillableAmount) { 1009 workRecord.clearValues("rate").add(rate); 1010 workRecord.clearValues("billableAmount").add( 1012 rate.multiply( 1013 new BigDecimal (durationHours.intValue()) 1014 ).add( 1015 rate.multiply(new BigDecimal (durationMinutes.intValue()).divide(new BigDecimal (60), 2, BigDecimal.ROUND_DOWN)) 1016 ) 1017 ); 1018 } 1019 if(updateWorkCompoundBooking) { 1021 if(workRecord.values("workCb").size() > 0) { 1022 this.plugin.depots.removeCompoundBooking( 1023 header, 1024 (Path)workRecord.getValues("workCb").get(0) 1025 ); 1026 } 1027 DataproviderObject_1_0 depotCredit = null; 1030 Path resourceIdentity = (Path)resourceAssignment.values("resource").get(0); 1031 List depotReferences = null; 1032 if(resourceIdentity == null) { 1033 depotReferences = Collections.EMPTY_LIST; 1034 } 1035 else { 1036 depotReferences = this.delegation.addFindRequest( 1037 resourceIdentity.getChild("depotReference"), 1038 null, 1039 AttributeSelectors.ALL_ATTRIBUTES, 1040 0, 1041 Integer.MAX_VALUE, 1042 Directions.ASCENDING 1043 ); 1044 } 1045 for( 1046 Iterator j = depotReferences.iterator(); 1047 j.hasNext(); 1048 ) { 1049 DataproviderObject_1_0 depotReference = (DataproviderObject_1_0)j.next(); 1050 Number depotUsage = (Number )depotReference.values("depotUsage").get(0); 1051 if((depotUsage != null) && (depotUsage.shortValue() == Depots.DEPOT_USAGE_WORK_EFFORT)) { 1052 depotCredit = this.plugin.retrieveObjectFromLocal( 1053 header, 1054 (Path)depotReference.values("depot").get(0) 1055 ); 1056 } 1057 } 1058 DataproviderObject_1_0 depotDebit = null; 1061 DataproviderObject_1_0 activity = this.plugin.retrieveObjectFromDelegation( 1062 workRecord.path().getPrefix(workRecord.path().size() - 4) 1063 ); 1064 depotReferences = this.delegation.addFindRequest( 1065 activity.path().getChild("depotReference"), 1066 null, 1067 AttributeSelectors.ALL_ATTRIBUTES, 1068 0, 1069 Integer.MAX_VALUE, 1070 Directions.ASCENDING 1071 ); 1072 for( 1073 Iterator j = depotReferences.iterator(); 1074 j.hasNext(); 1075 ) { 1076 DataproviderObject_1_0 depotReference = (DataproviderObject_1_0)j.next(); 1077 Number depotUsage = (Number )depotReference.values("depotUsage").get(0); 1078 if((depotUsage != null) && (depotUsage.shortValue() == Depots.DEPOT_USAGE_WORK_EFFORT)) { 1079 depotDebit = this.plugin.retrieveObjectFromLocal( 1080 header, 1081 (Path)depotReference.values("depot").get(0) 1082 ); 1083 } 1084 } 1085 Path activityTypeIdentity = (Path)activity.values("activityType").get(0); 1086 if( 1087 (depotCredit != null) && 1088 (depotDebit != null) && 1089 (activityTypeIdentity != null) 1090 ) { 1091 if(!depotCredit.path().getPrefix(7).equals(depotDebit.path().getPrefix(7))) { 1092 throw new ServiceException( 1093 OpenCrxException.DOMAIN, 1094 OpenCrxException.DEPOT_POSITION_IS_LOCKED, 1095 new BasicException.Parameter[]{ 1096 new BasicException.Parameter("param0", depotDebit.path()), 1097 new BasicException.Parameter("param1", depotCredit.path()) 1098 }, 1099 "Depot entity not equal" 1100 ); 1101 } 1102 else { 1103 DataproviderObject_1_0 activityType = this.plugin.retrieveObjectFromDelegation( 1104 activityTypeIdentity 1105 ); 1106 String valueDate = (String )workRecord.values("endedAt").get(0); 1107 Path positionCreditIdentity = this.plugin.depots.openDepotPosition( 1108 header, 1109 depotCredit, 1110 (String )activityType.values("name").get(0), 1111 (String )activityType.values("description").get(0), 1112 valueDate, null, 1114 null, 1115 null, 1116 Boolean.FALSE 1117 ).path(); 1118 Path positionDebitIdentity = this.plugin.depots.openDepotPosition( 1119 header, 1120 depotDebit, 1121 (String )activityType.values("name").get(0), 1122 (String )activityType.values("description").get(0), 1123 valueDate, null, 1125 null, 1126 null, 1127 Boolean.FALSE 1128 ).path(); 1129 DataproviderObject_1_0 workCb = 1130 this.plugin.depots.createCreditDebitBooking( 1131 header, 1132 depotCredit.path().getPrefix(7), 1133 (String )workRecord.values("endedAt").get(0), 1134 Depots.BOOKING_TYPE_STANDARD, 1135 new BigDecimal (durationHours.intValue()).add(new BigDecimal (durationMinutes.intValue()).divide(new BigDecimal (60), 2, BigDecimal.ROUND_DOWN)), 1136 BOOKING_TEXT_NAME_WORK_EFFORT, 1137 (Path)activityType.values("workBt").get(0), 1138 positionCreditIdentity, 1139 positionDebitIdentity, 1140 null, 1141 workRecord.path(), 1142 null 1143 ); 1144 workRecord.clearValues("workCb").add( 1145 workCb.path() 1146 ); 1147 } 1148 } 1149 } 1150 } 1151 } 1152 1153 public DataproviderObject addWorkRecord( 1155 ServiceHeader header, 1156 Path resourceIdentity, 1157 Path activityIdentity, 1158 String name, 1159 String description, 1160 String startedAt, 1161 String endedAt, 1162 Number durationHours, 1163 Number durationMinutes, 1164 Number pauseDurationHours, 1165 Number pauseDurationMinutes, 1166 Number rateType, 1167 short durationCalculationMode 1168 ) throws ServiceException { 1169 DataproviderObject workRecord = null; 1170 if(activityIdentity != null) { 1171 List resourceAssignments = this.delegation.addFindRequest( 1172 activityIdentity.getChild("assignedResource"), 1173 new FilterProperty[]{ 1174 new FilterProperty( 1175 Quantors.THERE_EXISTS, 1176 "resource", 1177 FilterOperators.IS_IN, 1178 new Object []{resourceIdentity} 1179 ) 1180 } 1181 ); 1182 if(resourceAssignments.size() > 0) { 1183 DataproviderObject_1_0 resource = this.plugin.retrieveObjectFromDelegation( 1184 resourceIdentity 1185 ); 1186 Path resourceAssignmentIdentity = 1187 ((DataproviderObject_1_0)resourceAssignments.iterator().next()).path(); 1188 workRecord = new DataproviderObject( 1189 resourceAssignmentIdentity.getDescendant(new String []{"workRecord", this.plugin.getUidAsString()}) 1190 ); 1191 workRecord.values(SystemAttributes.OBJECT_CLASS).add( 1192 "org:opencrx:kernel:activity1:ActivityWorkRecord" 1193 ); 1194 if(name != null) { 1195 workRecord.values("name").add(name); 1196 } 1197 if(description != null) { 1198 workRecord.values("description").add(description); 1199 } 1200 workRecord.values("startedAt").add( 1201 startedAt == null 1202 ? DateFormat.getInstance().format(new Date ()).substring(0, 8) + "T000000.000Z" 1203 : startedAt 1204 ); 1205 Date startedAtAsDate = null; 1206 try { 1207 startedAtAsDate = startedAt == null 1208 ? null 1209 : DateFormat.getInstance().parse(startedAt); 1210 } 1211 catch(ParseException e) {} 1212 workRecord.values("endedAt").add( 1213 endedAt == null 1214 ? startedAt == null 1215 ? DateFormat.getInstance().format(new Date (System.currentTimeMillis() + 86400000L)).substring(0, 8) + "T000000.000Z" 1216 : DateFormat.getInstance().format(new Date (startedAtAsDate.getTime() + 86400000L)).substring(0, 8) + "T000000.000Z" 1217 : endedAt 1218 ); 1219 if(durationHours != null) { 1220 workRecord.values("durationHours").add(durationHours); 1221 } 1222 if(durationMinutes != null) { 1223 workRecord.values("durationMinutes").add(durationMinutes); 1224 } 1225 if(pauseDurationHours != null) { 1226 workRecord.values("pauseDurationHours").add(pauseDurationHours); 1227 } 1228 if(pauseDurationMinutes != null) { 1229 workRecord.values("pauseDurationMinutes").add(pauseDurationMinutes); 1230 } 1231 workRecord.values("durationCalculationMode").add( 1232 new Short (durationCalculationMode) 1233 ); 1234 workRecord.values("isBillable").add(Boolean.TRUE); 1235 workRecord.values("billingCurrency").addAll( 1236 resource.values("rateCurrency") 1237 ); 1238 workRecord.values("rateType").add( 1239 rateType == null 1240 ? new Short (RATE_TYPE_NA) 1241 : rateType 1242 ); 1243 this.plugin.createObject( 1244 workRecord 1245 ); 1246 this.updateWorkRecord( 1247 header, 1248 this.plugin.retrieveObjectForModification(workRecord.path()), 1249 null 1250 ); 1251 } 1252 } 1253 return workRecord; 1254 } 1255 1256 public DataproviderObject addWorkRecordByPeriod( 1258 ServiceHeader header, 1259 DataproviderObject_1_0 resource, 1260 DataproviderObject_1_0 params 1261 ) throws ServiceException { 1262 return this.addWorkRecord( 1263 header, 1264 resource.path(), 1265 (Path)params.values("activity").get(0), 1266 (String )params.values("name").get(0), 1267 (String )params.values("description").get(0), 1268 (String )params.values("startAt").get(0), 1269 (String )params.values("endAt").get(0), 1270 null, 1271 null, 1272 (Number )params.values("pauseDurationHours").get(0), 1273 (Number )params.values("pauseDurationMinutes").get(0), 1274 (Number )params.values("rateType").get(0), 1275 Activities.DURATION_CALCULATION_MODE_CALC_DURATION 1276 ); 1277 } 1278 1279 public DataproviderObject addWorkRecordByCalendar( 1281 ServiceHeader header, 1282 DataproviderObject_1_0 resource, 1283 DataproviderObject_1_0 params 1284 ) throws ServiceException { 1285 Path activityIdentity = (Path)params.values("activity").get(0); 1286 if(activityIdentity == null) return null; 1287 List resourceAssignments = this.delegation.addFindRequest( 1289 activityIdentity.getChild("assignedResource"), 1290 new FilterProperty[]{ 1291 new FilterProperty( 1292 Quantors.THERE_EXISTS, 1293 "resource", 1294 FilterOperators.IS_IN, 1295 new Object []{resource.path()} 1296 ) 1297 }, 1298 AttributeSelectors.ALL_ATTRIBUTES, 1299 0, 1300 Integer.MAX_VALUE, 1301 Directions.ASCENDING 1302 ); 1303 if(resourceAssignments.size() == 0) return null; 1304 DataproviderObject_1_0 resourceAssignment = 1305 (DataproviderObject_1_0)resourceAssignments.iterator().next(); 1306 Path calendarIdentity = resourceAssignment.values("calendar").size() > 0 1308 ? (Path)resourceAssignment.values("calendar").get(0) 1309 : (Path)resource.values("calendar").get(0); 1310 if(calendarIdentity == null) return null; 1311 String startAt = (String )params.values("startAt").get(0); 1312 GregorianCalendar currentCal = new GregorianCalendar ( 1313 Integer.parseInt(startAt.substring(0, 4)), 1314 Integer.parseInt(startAt.substring(4, 6)) - 1, 1315 Integer.parseInt(startAt.substring(6, 8)) 1316 ); 1317 String endAt = (String )params.values("endAt").get(0); 1318 GregorianCalendar endAtCal = new GregorianCalendar ( 1319 Integer.parseInt(endAt.substring(0, 4)), 1320 Integer.parseInt(endAt.substring(4, 6)) - 1, 1321 Integer.parseInt(endAt.substring(6, 8)) 1322 ); 1323 int workDurationPercentage = resourceAssignment.values("workDurationPercentage").size() > 0 1325 ? ((Number )resourceAssignment.values("workDurationPercentage").get(0)).intValue() 1326 : 0; 1327 int count = 0; 1329 DataproviderObject workRecord = null; 1330 while(!currentCal.after(endAtCal)) { 1331 DataproviderObject_1_0 workingDay = 1332 this.findWorkingDay( 1333 calendarIdentity, 1334 currentCal 1335 ); 1336 if( 1337 (workingDay != null) && 1338 (workingDay.values("isWorkingDay").size() > 0) && 1339 ((Boolean )workingDay.values("isWorkingDay").get(0)).booleanValue() 1340 ) { 1341 int workDurationHours = 1342 (workDurationPercentage * ((Number )workingDay.values("workDurationHours").get(0)).intValue()) / 100; 1343 int workDurationMinutes = 1344 (workDurationPercentage * ((Number )workingDay.values("workDurationMinutes").get(0)).intValue()) / 100; 1345 workDurationHours += workDurationMinutes / 60; 1346 workDurationMinutes %= 60; 1347 if( 1348 (workDurationHours > 0) || 1349 (workDurationMinutes > 0) 1350 ) { 1351 int year = currentCal.get(GregorianCalendar.YEAR); 1352 int month = currentCal.get(GregorianCalendar.MONTH) + 1; 1353 int day = currentCal.get(GregorianCalendar.DAY_OF_MONTH); 1354 String currentDate = "" + 1355 year + 1356 (month < 10 ? "0" : "") + month + 1357 (day < 10 ? "0" : "") + day; 1358 int workHourStartAt = java.lang.Math.max(0, (24 - (workDurationHours + 1)) / 2); 1359 int workHoursEndAt = java.lang.Math.min(23, workHourStartAt + workDurationHours + 1); 1360 workRecord = 1361 this.addWorkRecord( 1362 header, 1363 resource.path(), 1364 activityIdentity, 1365 (String )params.values("name").get(0) + " #" + count, 1366 (String )params.values("description").get(0), 1367 currentDate + "T" + (workHourStartAt < 10 ? "0" : "") + workHourStartAt + "0000.000Z", 1368 currentDate + "T" + (workHoursEndAt < 10 ? "0" : "") + workHoursEndAt + "0000.000Z", 1369 new Integer (workDurationHours), 1370 new Integer (workDurationMinutes), 1371 null, 1372 null, 1373 (Number )params.values("rateType").get(0), 1374 Activities.DURATION_CALCULATION_MODE_CALC_PAUSE 1375 ); 1376 count++; 1377 } 1378 } 1379 currentCal.add( 1380 GregorianCalendar.DAY_OF_MONTH, 1381 1 1382 ); 1383 } 1384 return workRecord; 1385 } 1386 1387 public DataproviderObject addWorkRecordByDuration( 1389 ServiceHeader header, 1390 DataproviderObject_1_0 resource, 1391 DataproviderObject_1_0 params 1392 ) throws ServiceException { 1393 return this.addWorkRecord( 1394 header, 1395 resource.path(), 1396 (Path)params.values("activity").get(0), 1397 (String )params.values("name").get(0), 1398 (String )params.values("description").get(0), 1399 params.values("startAt").size() > 0 1401 ? params.values("startAt").get(0) + "T000000.000Z" 1402 : null, 1403 params.values("endAt").size() > 0 1405 ? params.values("endAt").get(0) + "T000000.000Z" 1406 : null, 1407 (Number )params.values("durationHours").get(0), 1408 (Number )params.values("durationMinutes").get(0), 1409 null, 1410 null, 1411 (Number )params.values("rateType").get(0), 1412 Activities.DURATION_CALCULATION_MODE_CALC_PAUSE 1413 ); 1414 } 1415 1416 public void removeWorkRecord( 1418 ServiceHeader header, 1419 Path workRecordIdentity 1420 ) throws ServiceException { 1421 DataproviderObject_1_0 workRecord = this.plugin.retrieveObjectFromDelegation(workRecordIdentity); 1422 if(workRecord.values("workCb").size() > 0) { 1423 this.plugin.depots.removeCompoundBooking( 1424 header, 1425 (Path)workRecord.values("workCb").get(0) 1426 ); 1427 this.plugin.removeObject( 1428 workRecordIdentity 1429 ); 1430 } 1431 } 1432 1433 public void removeActivityGroup( 1435 ServiceHeader header, 1436 Path activityGroupIdentity 1437 ) throws ServiceException { 1438 List activities = this.delegation.addFindRequest( 1439 activityGroupIdentity.getChild("filteredActivity"), 1440 null 1441 ); 1442 if(activities.size() > 0) { 1444 throw new ServiceException( 1445 OpenCrxException.DOMAIN, 1446 OpenCrxException.ACTIVITY_GROUP_HAS_ASSIGNED_ACTIVITIES, 1447 new BasicException.Parameter[]{ 1448 new BasicException.Parameter("param0", activityGroupIdentity) 1449 }, 1450 "Activity group has assigned activities. Can not remove." 1451 ); 1452 } 1453 else { 1454 this.plugin.removeObject( 1455 activityGroupIdentity 1456 ); 1457 } 1458 } 1459 1460 public void updateActivity( 1462 DataproviderObject object, 1463 DataproviderObject_1_0 oldValues 1464 ) throws ServiceException { 1465 if(this.plugin.isActivity(object)) { 1466 if(oldValues != null) { 1467 List votes = this.delegation.addFindRequest( 1468 object.path().getChild("vote"), 1469 null, 1470 AttributeSelectors.ALL_ATTRIBUTES, 1471 0, Integer.MAX_VALUE, Directions.ASCENDING 1472 ); 1473 object.clearValues("totalVotes").add( 1474 new Integer (votes.size()) 1475 ); 1476 } 1477 if(oldValues == null) { 1478 if((object.getValues("dueBy") == null) || (object.values("dueBy").size() == 0)) { 1480 object.clearValues("dueBy").add(MAX_DATE); 1481 } 1482 if((object.getValues("percentComplete") == null) || (object.values("percentComplete").size() == 0)) { 1484 object.clearValues("percentComplete").add(new Short ((short)0)); 1485 } 1486 } 1487 } 1488 } 1489 1490 public void reapplyActivityCreator( 1492 ServiceHeader header, 1493 Path activityIdentity, 1494 Path activityCreatorIdentity 1495 ) throws ServiceException { 1496 if(activityCreatorIdentity != null) { 1497 DataproviderObject_1_0 activityCreator = this.plugin.retrieveObjectFromDelegation( 1498 activityCreatorIdentity 1499 ); 1500 Path activityTypeIdentity = (Path)activityCreator.values("activityType").get(0); 1501 if(activityTypeIdentity != null) { 1502 DataproviderObject_1_0 activityType = this.plugin.retrieveObjectFromDelegation( 1503 activityTypeIdentity 1504 ); 1505 DataproviderObject activity = this.plugin.retrieveObjectForModification( 1506 activityIdentity 1507 ); 1508 if( 1510 ACTIVITY_TYPES[((Number )activityType.values("activityClass").get(0)).intValue()].equals( 1511 activity.values(SystemAttributes.OBJECT_CLASS).get(0) 1512 ) 1513 ) { 1514 List activityGroupsIdentities = activityCreator.values("activityGroup"); 1519 Set owningGroups = new HashSet (); 1520 for(Iterator i = activityGroupsIdentities.iterator(); i.hasNext(); ) { 1521 DataproviderObject_1_0 activityGroup = this.plugin.retrieveObjectFromDelegation( 1522 (Path)i.next() 1523 ); 1524 owningGroups.addAll( 1525 activityGroup.values("owningGroup") 1526 ); 1527 } 1528 activity.clearValues("owningGroup").addAll( 1529 owningGroups 1530 ); 1531 1532 List existingGroupAssignments = this.delegation.addFindRequest( 1535 activityIdentity.getChild("assignedGroup"), 1536 null, 1537 AttributeSelectors.ALL_ATTRIBUTES, 1538 0, 1539 Integer.MAX_VALUE, 1540 Directions.ASCENDING 1541 ); 1542 List excludes = new ArrayList (); 1543 for(Iterator i = existingGroupAssignments.iterator(); i.hasNext(); ) { 1544 DataproviderObject_1_0 existingGroupAssignment = (DataproviderObject_1_0)i.next(); 1545 if(existingGroupAssignment.values("activityGroup").size() > 0) { 1546 excludes.add( 1547 existingGroupAssignment.values("activityGroup").get(0) 1548 ); 1549 } 1550 } 1551 for(Iterator i = activityGroupsIdentities.iterator(); i.hasNext(); ) { 1553 Path activityGroupIdentity = (Path)i.next(); 1554 if(!excludes.contains(activityGroupIdentity)) { 1555 DataproviderObject activityGroupAssignment = new DataproviderObject( 1556 activityIdentity.getDescendant(new String []{"assignedGroup", this.plugin.getUidAsString()}) 1557 ); 1558 activityGroupAssignment.values(SystemAttributes.OBJECT_CLASS).add( 1559 "org:opencrx:kernel:activity1:ActivityGroupAssignment" 1560 ); 1561 activityGroupAssignment.values("activityGroup").add( 1562 activityGroupIdentity 1563 ); 1564 this.plugin.createObject( 1565 activityGroupAssignment 1566 ); 1567 } 1568 } 1569 List resources = new ArrayList (); 1571 if(activityCreator.values("resource").size() > 0) { 1572 resources = activityCreator.values("resource"); 1573 } 1574 else { 1575 List allResources = this.delegation.addFindRequest( 1577 activityIdentity.getPrefix(5).getChild("resource"), 1578 new FilterProperty[]{ 1579 new FilterProperty( 1580 Quantors.THERE_EXISTS, 1581 "contact", 1582 FilterOperators.IS_IN, 1583 new Object []{this.plugin.getUserHome(header, activityIdentity).values("contact").get(0)} 1584 ) 1585 } 1586 ); 1587 if(allResources.size() > 0) { 1588 resources.add( 1589 ((DataproviderObject_1_0)allResources.iterator().next()).path() 1590 ); 1591 } 1592 } 1593 List existingResourceAssignments = this.delegation.addFindRequest( 1595 activityIdentity.getChild("assignedResource"), 1596 null, 1597 AttributeSelectors.ALL_ATTRIBUTES, 1598 0, 1599 Integer.MAX_VALUE, 1600 Directions.ASCENDING 1601 ); 1602 excludes = new ArrayList (); 1603 for(Iterator i = existingResourceAssignments.iterator(); i.hasNext(); ) { 1604 DataproviderObject_1_0 existingResourceAssignment = (DataproviderObject_1_0)i.next(); 1605 if(existingResourceAssignment.values("resource").size() > 0) { 1606 excludes.add( 1607 existingResourceAssignment.values("resource").get(0) 1608 ); 1609 } 1610 } 1611 int ii = 0; 1612 for(Iterator i = resources.iterator(); i.hasNext(); ii++) { 1613 Path resourceIdentity = (Path)i.next(); 1614 if(!excludes.contains(resourceIdentity)) { 1615 DataproviderObject_1_0 resource = this.plugin.retrieveObjectFromDelegation( 1616 resourceIdentity 1617 ); 1618 DataproviderObject resourceAssignment = new DataproviderObject( 1619 activityIdentity.getDescendant(new String []{"assignedResource", this.plugin.getUidAsString()}) 1620 ); 1621 resourceAssignment.values(SystemAttributes.OBJECT_CLASS).add( 1622 "org:opencrx:kernel:activity1:ResourceAssignment" 1623 ); 1624 resourceAssignment.values("name").addAll( 1625 resource.values("name") 1626 ); 1627 resourceAssignment.values("description").add( 1628 "#" + activity.values("activityNumber").get(0) + ": " + 1629 (activity.values("name").size() > 0 ? activity.values("name").get(0) : "") 1630 ); 1631 resourceAssignment.values("resource").add( 1632 resourceIdentity 1633 ); 1634 resourceAssignment.values("resourceRole").add( 1635 new Short ((short)0) 1636 ); 1637 resourceAssignment.values("resourceOrder").add( 1638 new Short ((short)ii) 1639 ); 1640 resourceAssignment.values("workDurationPercentage").add( 1641 new Short ((short)100) 1642 ); 1643 this.plugin.createObject( 1644 resourceAssignment 1645 ); 1646 } 1647 } 1648 List existingDepotReferences = this.delegation.addFindRequest( 1650 activityIdentity.getChild("depotReference"), 1651 null, 1652 AttributeSelectors.ALL_ATTRIBUTES, 1653 0, 1654 Integer.MAX_VALUE, 1655 Directions.ASCENDING 1656 ); 1657 excludes = new ArrayList (); 1658 for(Iterator i = existingDepotReferences.iterator(); i.hasNext(); ) { 1659 DataproviderObject_1_0 existingDepotReference = (DataproviderObject_1_0)i.next(); 1660 excludes.add( 1661 new Short (((Number )existingDepotReference.values("depotUsage").get(0)).shortValue()) 1662 ); 1663 } 1664 List depotReferences = this.delegation.addFindRequest( 1665 activityCreator.path().getChild("depotReference"), 1666 null, 1667 AttributeSelectors.ALL_ATTRIBUTES, 1668 0, 1669 Integer.MAX_VALUE, 1670 Directions.ASCENDING 1671 ); 1672 for( 1673 Iterator i = depotReferences.iterator(); 1674 i.hasNext(); 1675 ) { 1676 DataproviderObject_1_0 depotReference = (DataproviderObject_1_0)i.next(); 1677 if(!excludes.contains(new Short (((Number )depotReference.values("depotUsage").get(0)).shortValue()))) { 1678 this.plugin.cloneable.cloneAndUpdateReferences( 1679 header, 1680 depotReference, 1681 activityIdentity.getChild("depotReference"), 1682 null, 1683 "", 1684 true 1685 ); 1686 } 1687 } 1688 activity.clearValues("activityType").add( 1690 activityTypeIdentity 1691 ); 1692 activity.clearValues("processState"); 1693 activity.clearValues("lastTransition"); 1694 if(activityType.values("controlledBy").size() > 0) { 1695 DataproviderObject_1_0 activityProcess = this.plugin.retrieveObjectFromDelegation( 1696 (Path)activityType.values("controlledBy").get(0) 1697 ); 1698 DataproviderObject_1_0 lastTransition = null; 1701 Path processStateIdentity = null; 1702 if(activity.values("percentComplete").size() > 0) { 1703 List transitions = 1704 this.delegation.addFindRequest( 1705 activityProcess.path().getChild("transition"), 1706 new FilterProperty[]{ 1707 new FilterProperty( 1708 Quantors.THERE_EXISTS, 1709 "newPercentComplete", 1710 FilterOperators.IS_IN, 1711 new Object []{activity.values("percentComplete").get(0)} 1712 ) 1713 }, 1714 AttributeSelectors.ALL_ATTRIBUTES, 1715 0, 1716 Integer.MAX_VALUE, 1717 Directions.ASCENDING 1718 ); 1719 if(transitions.size() > 0) { 1720 lastTransition = (DataproviderObject_1_0)transitions.iterator().next(); 1721 processStateIdentity = (Path)lastTransition.values("nextState").get(0); 1722 } 1723 } 1724 if( 1725 (lastTransition == null) && 1726 (activity.values("activityState").size() > 0) 1727 ) { 1728 List transitions = 1729 this.delegation.addFindRequest( 1730 activityProcess.path().getChild("transition"), 1731 new FilterProperty[]{ 1732 new FilterProperty( 1733 Quantors.THERE_EXISTS, 1734 "newActivityState", 1735 FilterOperators.IS_IN, 1736 new Object []{activity.values("activityState").get(0)} 1737 ) 1738 }, 1739 AttributeSelectors.ALL_ATTRIBUTES, 1740 0, 1741 Integer.MAX_VALUE, 1742 Directions.ASCENDING 1743 ); 1744 if(transitions.size() > 0) { 1745 lastTransition = (DataproviderObject_1_0)transitions.iterator().next(); 1746 processStateIdentity = (Path)lastTransition.values("nextState").get(0); 1747 } 1748 } 1749 if(lastTransition == null) { 1750 lastTransition = null; 1751 processStateIdentity = (Path)activityProcess.values("startState").get(0); 1752 } 1753 if(processStateIdentity != null) { 1754 activity.values("processState").add(processStateIdentity); 1755 } 1756 if(lastTransition != null) { 1757 activity.values("lastTransition").add(lastTransition.path()); 1758 activity.clearValues("percentComplete").addAll(lastTransition.values("newPercentComplete")); 1759 activity.clearValues("activityState").addAll(lastTransition.values("newActivityState")); 1760 } 1761 } 1762 } 1763 } 1764 } 1765 } 1766 1767 public FilterProperty[] getActivityFilterProperties( 1769 Path activityFilterIdentity 1770 ) throws ServiceException { 1771 List filterProperties = this.delegation.addFindRequest( 1772 activityFilterIdentity.getChild("filterProperty"), 1773 null, 1774 AttributeSelectors.ALL_ATTRIBUTES, 1775 null, 1776 0, 1777 Integer.MAX_VALUE, 1778 Directions.ASCENDING 1779 ); 1780 List filter = new ArrayList (); 1781 for( 1782 Iterator i = filterProperties.iterator(); 1783 i.hasNext(); 1784 ) { 1785 DataproviderObject_1_0 filterProperty = (DataproviderObject_1_0)i.next(); 1786 String filterPropertyClass = (String )filterProperty.values(SystemAttributes.OBJECT_CLASS).get(0); 1787 1788 Boolean isActive = (Boolean )filterProperty.values("isActive").get(0); 1789 1790 if((isActive != null) && isActive.booleanValue()) { 1791 short filterOperator = filterProperty.values("filterOperator").size() == 0 1793 ? FilterOperators.IS_IN 1794 : ((Number )filterProperty.values("filterOperator").get(0)).shortValue(); 1795 filterOperator = filterOperator == 0 1796 ? FilterOperators.IS_IN 1797 : filterOperator; 1798 short filterQuantor = filterProperty.values("filterQuantor").size() == 0 1799 ? Quantors.THERE_EXISTS 1800 : ((Number )filterProperty.values("filterQuantor").get(0)).shortValue(); 1801 filterQuantor = filterQuantor == 0 1802 ? Quantors.THERE_EXISTS 1803 : filterQuantor; 1804 1805 if("org:opencrx:kernel:activity1:ActivityStateFilterProperty".equals(filterPropertyClass)) { 1806 filter.add( 1807 new FilterProperty( 1808 filterQuantor, 1809 "activityState", 1810 filterOperator, 1811 filterProperty.values("activityState").toArray() 1812 ) 1813 ); 1814 } 1815 else if("org:opencrx:kernel:activity1:ResourceNameFilterProperty".equals(filterPropertyClass)) { 1816 filter.add( 1817 new FilterProperty( 1818 filterQuantor, 1819 "p$$resourceName", 1820 filterOperator, 1821 filterProperty.values("resourceName").toArray() 1822 ) 1823 ); 1824 } 1825 else if("org:opencrx:kernel:activity1:ResourceRoleFilterProperty".equals(filterPropertyClass)) { 1826 filter.add( 1827 new FilterProperty( 1828 filterQuantor, 1829 "p$$resourceRole", 1830 filterOperator, 1831 filterProperty.values("resourceRole").toArray() 1832 ) 1833 ); 1834 } 1835 else if("org:opencrx:kernel:activity1:ScheduledStartFilterProperty".equals(filterPropertyClass)) { 1836 filter.add( 1837 new FilterProperty( 1838 filterQuantor, 1839 "scheduledStart", 1840 filterOperator, 1841 filterProperty.values("scheduledStart").toArray() 1842 ) 1843 ); 1844 } 1845 else if("org:opencrx:kernel:activity1:ScheduledEndFilterProperty".equals(filterPropertyClass)) { 1846 filter.add( 1847 new FilterProperty( 1848 filterQuantor, 1849 "scheduledEnd", 1850 filterOperator, 1851 filterProperty.values("scheduledEnd").toArray() 1852 ) 1853 ); 1854 } 1855 else if("org:opencrx:kernel:activity1:ActivityProcessStateFilterProperty".equals(filterPropertyClass)) { 1856 filter.add( 1857 new FilterProperty( 1858 filterQuantor, 1859 "processState", 1860 filterOperator, 1861 filterProperty.values("processState").toArray() 1862 ) 1863 ); 1864 } 1865 else if("org:opencrx:kernel:activity1:ActivityTypeFilterProperty".equals(filterPropertyClass)) { 1866 filter.add( 1867 new FilterProperty( 1868 filterQuantor, 1869 "activityType", 1870 filterOperator, 1871 filterProperty.values("activityType").toArray() 1872 ) 1873 ); 1874 } 1875 else if("org:opencrx:kernel:activity1:ResourceFilterProperty".equals(filterPropertyClass)) { 1876 filter.add( 1877 new FilterProperty( 1878 filterQuantor, 1879 "p$$resource", 1880 filterOperator, 1881 filterProperty.values("resource").toArray() 1882 ) 1883 ); 1884 } 1885 else if("org:opencrx:kernel:activity1:ActivityGroupFilterProperty".equals(filterPropertyClass)) { 1886 filter.add( 1887 new FilterProperty( 1888 filterQuantor, 1889 "p$$activityGroup", 1890 filterOperator, 1891 filterProperty.values("activityGroup").toArray() 1892 ) 1893 ); 1894 } 1895 else if("org:opencrx:kernel:activity1:ActivityNumberFilterProperty".equals(filterPropertyClass)) { 1896 filter.add( 1897 new FilterProperty( 1898 filterQuantor, 1899 "activityNumber", 1900 filterOperator, 1901 filterProperty.values("activityNumber").toArray() 1902 ) 1903 ); 1904 } 1905 } 1906 } 1907 return (FilterProperty[])filter.toArray(new FilterProperty[filter.size()]); 1908 } 1909 1910 public DataproviderObject_1_0 findWorkingDay( 1912 Path calendarIdentity, 1913 GregorianCalendar dateOfDayAsCal 1914 ) throws ServiceException { 1915 int year = dateOfDayAsCal.get(GregorianCalendar.YEAR); 1916 int month = dateOfDayAsCal.get(GregorianCalendar.MONTH) + 1; 1917 int day = dateOfDayAsCal.get(GregorianCalendar.DAY_OF_MONTH); 1918 String dateOfDay = "" + 1919 year + 1920 (month < 10 ? "0" : "") + month + 1921 (day < 10 ? "0" : "") + day; 1922 List days = 1924 this.delegation.addFindRequest( 1925 calendarIdentity.getChild("calendarDay"), 1926 new FilterProperty[]{ 1927 new FilterProperty( 1928 Quantors.THERE_EXISTS, 1929 "dateOfDay", 1930 FilterOperators.IS_IN, 1931 new String []{dateOfDay} 1932 ) 1933 }, 1934 AttributeSelectors.ALL_ATTRIBUTES, 1935 0, 1936 Integer.MAX_VALUE, 1937 Directions.ASCENDING 1938 ); 1939 if(days.size() > 0) { 1940 return (DataproviderObject_1_0)days.iterator().next(); 1941 } 1942 int dayOfWeek = 1944 dateOfDayAsCal.get(GregorianCalendar.DAY_OF_WEEK) - dateOfDayAsCal.getFirstDayOfWeek() + 1; 1945 days = 1946 this.delegation.addFindRequest( 1947 calendarIdentity.getChild("weekDay"), 1948 new FilterProperty[]{ 1949 new FilterProperty( 1950 Quantors.THERE_EXISTS, 1951 "dayOfWeek", 1952 FilterOperators.IS_IN, 1953 new Number []{new Short ((short)dayOfWeek)} 1954 ) 1955 }, 1956 AttributeSelectors.ALL_ATTRIBUTES, 1957 0, 1958 Integer.MAX_VALUE, 1959 Directions.ASCENDING 1960 ); 1961 if(days.size() > 0) { 1962 return (DataproviderObject_1_0)days.iterator().next(); 1963 } 1964 DataproviderObject_1_0 calendar = this.plugin.retrieveObjectFromDelegation( 1966 calendarIdentity 1967 ); 1968 if(calendar.values("baseCalendar").size() > 0) { 1969 return this.findWorkingDay( 1970 (Path)calendar.values("baseCalendar").get(0), 1971 dateOfDayAsCal 1972 ); 1973 } 1974 return null; 1975 } 1976 1977 public void assignTo( 1979 ServiceHeader header, 1980 Path activityIdentity, 1981 Path resourceIdentity 1982 ) throws ServiceException { 1983 if(resourceIdentity != null) { 1984 DataproviderObject activity = this.plugin.retrieveObjectForModification( 1985 activityIdentity 1986 ); 1987 DataproviderObject_1_0 resource = this.plugin.retrieveObjectFromDelegation( 1988 resourceIdentity 1989 ); 1990 Path contactIdentity = (Path)resource.values("contact").get(0); 1991 activity.clearValues("assignedTo").add( 1992 contactIdentity 1993 ); 1994 } 1995 } 1996 1997 public void completeActualEffort( 1999 ServiceHeader header, 2000 DataproviderObject_1_0 target, 2001 String filterAttribute, 2002 Set fetchSet 2003 ) throws ServiceException { 2004 2005 if( 2007 (fetchSet == null) || fetchSet.contains("actualEffortHours") || fetchSet.contains("actualEffortMinutes") 2008 ) { 2009 List workReportEntries = this.delegation.addFindRequest( 2010 target.path().getPrefix(5).getChild("workReportEntry"), 2011 new FilterProperty[]{ 2012 new FilterProperty( 2013 Quantors.THERE_EXISTS, 2014 filterAttribute, 2015 FilterOperators.IS_IN, 2016 new Object []{target.path().getPrefix(7)} 2017 ) 2018 }, 2019 AttributeSelectors.ALL_ATTRIBUTES, 2020 0, 2021 Integer.MAX_VALUE, 2022 Directions.ASCENDING 2023 2024 ); 2025 BigDecimal actualEffortHours = new BigDecimal (0); 2026 BigDecimal actualEffortMinutes = new BigDecimal (0); 2027 for( 2028 Iterator i = workReportEntries.iterator(); 2029 i.hasNext(); 2030 ) { 2031 DataproviderObject workReportEntry = (DataproviderObject)i.next(); 2032 actualEffortHours = actualEffortHours.add( 2033 (BigDecimal )workReportEntry.values("durationHours").get(0) 2034 ); 2035 actualEffortMinutes = actualEffortMinutes.add( 2036 (BigDecimal )workReportEntry.values("durationMinutes").get(0) 2037 ); 2038 } 2039 target.clearValues("actualEffortHours").add( 2040 new Integer (actualEffortHours.intValue() + (actualEffortMinutes.intValue() / 60)) 2041 ); 2042 target.clearValues("actualEffortMinutes").add( 2043 new Integer (actualEffortMinutes.intValue() % 60) 2044 ); 2045 } 2046 } 2047 2048 public List completeActivity( 2050 ServiceHeader header, 2051 DataproviderObject_1_0 activity, 2052 Set fetchSet 2053 ) throws ServiceException { 2054 this.completeActualEffort( 2055 header, 2056 activity, 2057 "activity", 2058 fetchSet 2059 ); 2060 return Collections.EMPTY_LIST; 2061 } 2062 2063 public List completeActivityGroup( 2065 ServiceHeader header, 2066 DataproviderObject_1_0 activityGroup, 2067 Set fetchSet 2068 ) throws ServiceException { 2069 this.completeActualEffort( 2070 header, 2071 activityGroup, 2072 "p$$activityGroup", 2073 fetchSet 2074 ); 2075 return Collections.EMPTY_LIST; 2076 } 2077 2078 public static final String MAX_DATE = "99991231T000000.000Z"; 2082 2083 private final static int BATCHING_MODE_SIZE = 1000; 2084 2085 private static final String CODEVALUENAME_ACTIVITY_TYPE = "org:opencrx:kernel:activity1:ActivityType:activityClass"; 2086 2087 private static final String [] ACTIVITY_TYPES = 2088 new String []{ 2089 "org:opencrx:kernel:activity1:EMail", 2090 "org:opencrx:kernel:activity1:Fax", 2091 "org:opencrx:kernel:activity1:Incident", 2092 "org:opencrx:kernel:activity1:Mailing", 2093 "org:opencrx:kernel:activity1:Meeting", 2094 "org:opencrx:kernel:activity1:Mms", 2095 "org:opencrx:kernel:activity1:PhoneCall", 2096 "org:opencrx:kernel:activity1:Sms", 2097 "org:opencrx:kernel:activity1:Task", 2098 "org:opencrx:kernel:activity1:Absence", 2099 "org:opencrx:kernel:activity1:ExternalActivity", 2100 "org:opencrx:kernel:activity1:SalesVisit" 2101 }; 2102 2103 public static final short ACTIVITY_LINK_TYPE_IS_DERIVED_FROM = 97; 2105 2106 public static final short DURATION_CALCULATION_MODE_CALC_DURATION = 1; 2108 public static final short DURATION_CALCULATION_MODE_CALC_PAUSE = 2; 2109 2110 public static final short RATE_TYPE_NA = 0; 2112 public static final short RATE_TYPE_STANDARD = 1; 2113 public static final short RATE_TYPE_OVERTIME = 2; 2114 2115 private static final String BOOKING_TEXT_NAME_WORK_EFFORT = "work efforts"; 2117 2118 private final Model_1_0 model; 2119 private final OpenCrxKernel_1 plugin; 2120 private final RequestCollection delegation; 2121 private final RefPackage_1_0 rootPkg; 2122 2123} 2124 2125 | Popular Tags |