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.DateFormat ; 63 import java.text.ParseException ; 64 import java.util.ArrayList ; 65 import java.util.Arrays ; 66 import java.util.Date ; 67 import java.util.HashMap ; 68 import java.util.HashSet ; 69 import java.util.Iterator ; 70 import java.util.List ; 71 import java.util.Locale ; 72 import java.util.Map ; 73 import java.util.Set ; 74 75 import org.opencrx.kernel.generic.OpenCrxException; 76 import org.openmdx.application.log.AppLog; 77 import org.openmdx.base.accessor.jmi.cci.RefPackage_1_0; 78 import org.openmdx.base.exception.ServiceException; 79 import org.openmdx.compatibility.base.dataprovider.cci.AttributeSelectors; 80 import org.openmdx.compatibility.base.dataprovider.cci.AttributeSpecifier; 81 import org.openmdx.compatibility.base.dataprovider.cci.DataproviderObject; 82 import org.openmdx.compatibility.base.dataprovider.cci.DataproviderObject_1_0; 83 import org.openmdx.compatibility.base.dataprovider.cci.DataproviderRequest; 84 import org.openmdx.compatibility.base.dataprovider.cci.Directions; 85 import org.openmdx.compatibility.base.dataprovider.cci.Orders; 86 import org.openmdx.compatibility.base.dataprovider.cci.RequestCollection; 87 import org.openmdx.compatibility.base.dataprovider.cci.ServiceHeader; 88 import org.openmdx.compatibility.base.dataprovider.cci.SystemAttributes; 89 import org.openmdx.compatibility.base.marshalling.Marshaller; 90 import org.openmdx.compatibility.base.naming.Path; 91 import org.openmdx.compatibility.base.query.FilterOperators; 92 import org.openmdx.compatibility.base.query.FilterProperty; 93 import org.openmdx.compatibility.base.query.Quantors; 94 import org.openmdx.kernel.exception.BasicException; 95 import org.openmdx.model1.accessor.basic.cci.Model_1_0; 96 97 public class Contracts { 98 99 public Contracts( 101 Model_1_0 model, 102 OpenCrxKernel_1 plugin, 103 RequestCollection delegation, 104 RefPackage_1_0 rootPkg 105 ) { 106 this.model = model; 107 this.plugin = plugin; 108 this.delegation = delegation; 109 this.cloning = new Cloneable ( 110 model, 111 plugin, 112 delegation, 113 rootPkg 114 ); 115 this.rootPkg = rootPkg; 116 } 117 118 static void copyAbstractContract( 120 DataproviderObject_1_0 from, 121 DataproviderObject to 122 ) throws ServiceException { 123 to.addClones(from, true); 124 } 125 126 static void copyAbstractContractPosition( 128 DataproviderObject_1_0 from, 129 DataproviderObject to 130 ) throws ServiceException { 131 to.addClones(from, true); 132 } 133 134 private DataproviderObject_1_0 getCachedDescription( 136 Path path, 137 int contractLanguage 138 ) throws ServiceException { 139 String key = path + ":" + contractLanguage; 140 DataproviderObject_1_0 description = (DataproviderObject_1_0)this.cachedDescriptions.get(key); 141 if((description == null) && !this.cachedDescriptions.containsKey(key)) { 142 description = this.plugin.getAdditionalDescription( 143 path, 144 contractLanguage 145 ); 146 this.cachedDescriptions.put( 147 key, 148 description 149 ); 150 } 151 return description; 152 } 153 154 private DataproviderObject_1_0 getCachedObject( 156 ServiceHeader header, 157 Path path 158 ) throws ServiceException { 159 DataproviderObject_1_0 object = (DataproviderObject_1_0)this.cachedObjects.get(path); 160 if((object == null) && !this.cachedObjects.containsKey(path)) { 161 object = this.plugin.retrieveObjectFromLocal( 162 header, 163 path 164 ); 165 this.cachedObjects.put( 166 object.path(), 167 object 168 ); 169 } 170 return object; 171 } 172 173 public void calculateContractPosition( 175 ServiceHeader header, 176 DataproviderObject_1_0 contract, 177 DataproviderObject_1_0 position 178 ) throws ServiceException { 179 180 List deliveryInformations = this.delegation.addFindRequest( 182 position.path().getChild("deliveryInformation"), 183 null, 184 AttributeSelectors.ALL_ATTRIBUTES, 185 0, 186 Integer.MAX_VALUE, 187 Directions.ASCENDING 188 ); 189 BigDecimal quantityShipped = new BigDecimal (0); 190 for( 191 Iterator i = deliveryInformations.iterator(); 192 i.hasNext(); 193 ) { 194 DataproviderObject deliveryInformation = (DataproviderObject)i.next(); 195 quantityShipped = quantityShipped.add( 196 (BigDecimal )deliveryInformation.values("quantityShipped").get(0) 197 ); 198 } 199 200 BigDecimal quantity = position.values("quantity").size() > 0 202 ? (BigDecimal )position.values("quantity").get(0) 203 : new BigDecimal (0); 204 BigDecimal adjustedQuantity = quantity; 205 BigDecimal minQuantity = position.values("minQuantity").size() > 0 206 ? (BigDecimal )position.values("minQuantity").get(0) 207 : new BigDecimal (0); 208 BigDecimal maxQuantity = position.values("maxQuantity").size() > 0 209 ? (BigDecimal )position.values("maxQuantity").get(0) 210 : new BigDecimal (Double.MAX_VALUE); 211 BigDecimal offsetQuantity = position.values("offsetQuantity").size() > 0 212 ? (BigDecimal )position.values("offsetQuantity").get(0) 213 : new BigDecimal (0); 214 short minMaxQuantityHandling = position.values("minMaxQuantityHandling").size() > 0 215 ? ((Number )position.values("minMaxQuantityHandling").get(0)).shortValue() 216 : MIN_MAX_QUANTITY_HANDLING_NA; 217 if(minMaxQuantityHandling == MIN_MAX_QUANTITY_HANDLING_LIMIT) { 218 adjustedQuantity = adjustedQuantity.subtract(offsetQuantity).max(minQuantity).min(maxQuantity); 219 } 220 221 BigDecimal pricePerUnit = position.values("pricePerUnit").size() > 0 223 ? (BigDecimal )position.values("pricePerUnit").get(0) 224 : new BigDecimal (0); 225 BigDecimal uomScaleFactor = new BigDecimal (1.0); 226 if( 227 (position.values("uom").size() > 0) && 228 (position.values("priceUom").size() > 0) && 229 !position.values("uom").get(0).equals(position.values("priceUom").get(0)) 230 ) { 231 DataproviderObject_1_0 priceUom = this.plugin.retrieveObjectFromLocal( 232 header, 233 (Path)position.values("priceUom").get(0) 234 ); 235 BigDecimal priceUomQuantity = priceUom.values("quantity").size() > 0 236 ? (BigDecimal )priceUom.values("quantity").get(0) 237 : new BigDecimal (0.0); 238 uomScaleFactor = position.values("uom").get(0).equals(priceUom.values("baseUom").get(0)) 239 ? priceUomQuantity.signum() == 0 240 ? new BigDecimal (0.0) 241 : new BigDecimal (1.0 / priceUomQuantity.doubleValue()) 242 : new BigDecimal (0.0); 243 } 244 BigDecimal baseAmount = adjustedQuantity.multiply(pricePerUnit.multiply(uomScaleFactor)); 245 Boolean discountIsPercentage = position.values("discountIsPercentage").size() > 0 247 ? (Boolean )position.values("discountIsPercentage").get(0) 248 : Boolean.FALSE; 249 BigDecimal discount = position.values("discount").size() > 0 250 ? (BigDecimal )position.values("discount").get(0) 251 : new BigDecimal (0); 252 BigDecimal discountAmount = discountIsPercentage.booleanValue() 254 ? baseAmount.multiply(discount.divide(new BigDecimal (100.0), BigDecimal.ROUND_UP)) 255 : adjustedQuantity.multiply(discount.multiply(uomScaleFactor)); 256 257 position.clearValues("baseAmount").add(baseAmount); 258 position.clearValues("discountAmount").add(discountAmount); 259 position.clearValues("quantityShipped").add(quantityShipped); 260 position.clearValues("quantityBackOrdered").add( 261 quantity.subtract(quantityShipped) 262 ); 263 264 BigDecimal salesTaxRate = new BigDecimal (0); 266 if(position.values("salesTaxType").size() > 0) { 267 try { 268 DataproviderObject_1_0 salesTaxType = this.getCachedObject( 269 header, 270 (Path)position.values("salesTaxType").get(0) 271 ); 272 if(salesTaxType.values("rate").size() > 0) { 273 salesTaxRate = (BigDecimal )salesTaxType.values("rate").get(0); 274 } 275 } catch(Exception e) {} 276 } 277 BigDecimal taxAmount = baseAmount.subtract(discountAmount).multiply(salesTaxRate.divide(new BigDecimal (100), BigDecimal.ROUND_UP)); 278 position.clearValues("taxAmount").add(taxAmount); 279 280 BigDecimal amount = baseAmount.subtract(discountAmount).add(taxAmount); 282 position.clearValues("amount").add(amount); 283 284 int contractLanguage = contract.values("contractLanguage").size() < 1 286 ? 0 287 : ((Number )contract.values("contractLanguage").get(0)).intValue(); 288 289 if(position.values("product").size() > 0) { 291 try { 292 DataproviderObject_1_0 product = this.delegation.addGetRequest( 293 (Path)position.values("product").get(0), 294 AttributeSelectors.ALL_ATTRIBUTES, 295 new AttributeSpecifier[]{} 296 ); 297 position.clearValues("productDescription").add( 298 product.values("description").get(0) 299 ); 300 position.clearValues("productDetailedDescription").add( 301 product.values("detailedDescription").get(0) 302 ); 303 DataproviderObject_1_0 additionalDescription = this.getCachedDescription( 304 product.path(), 305 contractLanguage 306 ); 307 if(additionalDescription != null) { 308 position.clearValues("productDescription").add( 309 additionalDescription.values("description").get(0) 310 ); 311 position.clearValues("productDetailedDescription").add( 312 additionalDescription.values("detailedDescription").get(0) 313 ); 314 } 315 } 316 catch(Exception e) { 317 new ServiceException(e).log(); 318 position.clearValues("productDescription").add("#ERR"); 319 position.clearValues("productDetailedDescription").add("#ERR"); 320 } 321 } 322 else { 323 position.clearValues("productDescription").add("N/A"); 324 position.clearValues("productDetailedDescription").add("N/A"); 325 } 326 327 if(position.values("uom").size() > 0) { 329 try { 330 DataproviderObject_1_0 uom = this.getCachedObject( 331 header, 332 (Path)position.values("uom").get(0) 333 ); 334 position.clearValues("uomDescription").add( 335 uom.values("description").get(0) 336 ); 337 position.clearValues("uomDetailedDescription").add( 338 uom.values("detailedDescription").get(0) 339 ); 340 DataproviderObject_1_0 additionalDescription = this.getCachedDescription( 341 uom.path(), 342 contractLanguage 343 ); 344 if(additionalDescription != null) { 345 position.clearValues("uomDescription").add( 346 additionalDescription.values("description").get(0) 347 ); 348 position.clearValues("uomDetailedDescription").add( 349 additionalDescription.values("detailedDescription").get(0) 350 ); 351 } 352 } 353 catch(Exception e) { 354 new ServiceException(e).log(); 355 position.clearValues("uomDescription").add("#ERR"); 356 position.clearValues("uomDetailedDescription").add("#ERR"); 357 } 358 } 359 else { 360 position.clearValues("uomDescription").add("N/A"); 361 position.clearValues("uomDetailedDescription").add("N/A"); 362 } 363 364 if(position.values("priceUom").size() > 0) { 366 try { 367 DataproviderObject_1_0 priceUom = this.getCachedObject( 368 header, 369 (Path)position.values("priceUom").get(0) 370 ); 371 position.clearValues("priceUomDescription").add( 372 priceUom.values("description").get(0) 373 ); 374 position.clearValues("priceUomDetailedDescription").add( 375 priceUom.values("detailedDescription").get(0) 376 ); 377 DataproviderObject_1_0 additionalDescription = this.getCachedDescription( 378 priceUom.path(), 379 contractLanguage 380 ); 381 if(additionalDescription != null) { 382 position.clearValues("priceUomDescription").add( 383 additionalDescription.values("description").get(0) 384 ); 385 position.clearValues("priceUomDetailedDescription").add( 386 additionalDescription.values("detailedDescription").get(0) 387 ); 388 } 389 } 390 catch(Exception e) { 391 new ServiceException(e).log(); 392 position.clearValues("priceUomDescription").add("#ERR"); 393 position.clearValues("priceUomDetailedDescription").add("#ERR"); 394 } 395 } 396 else { 397 position.clearValues("priceUomDescription").add("N/A"); 398 position.clearValues("priceUomDetailedDescription").add("N/A"); 399 } 400 401 if(position.values("salesTaxType").size() > 0) { 403 try { 404 DataproviderObject_1_0 salesTaxType = this.getCachedObject( 405 header, 406 (Path)position.values("salesTaxType").get(0) 407 ); 408 position.clearValues("salesTaxTypeDescription").add( 409 salesTaxType.values("description").get(0) 410 ); 411 position.clearValues("salesTaxTypeDetailedDescription").add( 412 salesTaxType.values("detailedDescription").get(0) 413 ); 414 DataproviderObject_1_0 additionalDescription = this.getCachedDescription( 415 salesTaxType.path(), 416 contractLanguage 417 ); 418 if(additionalDescription != null) { 419 position.clearValues("salesTaxTypeDescription").add( 420 additionalDescription.values("description").get(0) 421 ); 422 position.clearValues("salesTaxTypeDetailedDescription").add( 423 additionalDescription.values("detailedDescription").get(0) 424 ); 425 } 426 } 427 catch(Exception e) { 428 new ServiceException(e).log(); 429 position.clearValues("salesTaxTypeDescription").add("#ERR"); 430 position.clearValues("salesTaxTypeDetailedDescription").add("#ERR"); 431 } 432 } 433 else { 434 position.clearValues("salesTaxTypeDescription").add("N/A"); 435 position.clearValues("salesTaxTypeDetailedDescription").add("N/A"); 436 } 437 } 438 439 public void calculateContract( 441 ServiceHeader header, 442 DataproviderObject_1_0 contract, 443 Set fetchSet 444 ) throws ServiceException { 445 if(!this.plugin.isLead(contract)) { 446 Set derivedAttributes = new HashSet ( 447 Arrays.asList(new String []{"totalBaseAmount", "totalBaseAmount", "totalBaseAmount", "totalTaxAmount", "totalAmountIncludingTax", "totalSalesCommission"}) 448 ); 449 Path contractIdentity = new Path((String )contract.values(SystemAttributes.OBJECT_IDENTITY).get(0)); 450 if( 453 contractIdentity.equals(contract.path()) && 454 ((fetchSet == null) || derivedAttributes.removeAll(fetchSet)) 455 ) { 456 BigDecimal totalBaseAmount = new BigDecimal (0); 457 BigDecimal totalDiscountAmount = new BigDecimal (0); 458 BigDecimal totalTaxAmount = new BigDecimal (0); 459 BigDecimal totalSalesCommission = new BigDecimal (0); 460 List positions = this.delegation.addFindRequest( 461 contract.path().getChild("position"), 462 null, 463 AttributeSelectors.ALL_ATTRIBUTES, 464 0, 465 Integer.MAX_VALUE, 466 Directions.ASCENDING 467 ); 468 for( 469 Iterator i = positions.iterator(); 470 i.hasNext(); 471 ) { 472 DataproviderObject_1_0 position = (DataproviderObject_1_0)i.next(); 473 this.calculateContractPosition( 474 header, 475 contract, 476 position 477 ); 478 totalBaseAmount = totalBaseAmount.add( 479 (BigDecimal )position.values("baseAmount").get(0) 480 ); 481 BigDecimal discountAmount = (BigDecimal )position.values("discountAmount").get(0); 482 totalDiscountAmount = totalDiscountAmount.add(discountAmount); 483 totalTaxAmount = totalTaxAmount.add( 484 (BigDecimal )position.values("taxAmount").get(0) 485 ); 486 BigDecimal salesCommission = position.values("salesCommission").size() > 0 487 ? (BigDecimal )position.values("salesCommission").get(0) 488 : new BigDecimal (0); 489 BigDecimal baseAmount = (BigDecimal )position.values("baseAmount").get(0); 490 totalSalesCommission = totalSalesCommission.add( 491 (position.values("salesCommissionIsPercentage").size() > 0) && 492 (((Boolean )position.values("salesCommissionIsPercentage").get(0)).booleanValue()) 493 ? baseAmount.subtract(discountAmount).multiply(salesCommission.divide(new BigDecimal (100), BigDecimal.ROUND_UP)) 494 : salesCommission 495 ); 496 } 497 BigDecimal totalAmount = totalBaseAmount.subtract(totalDiscountAmount); 498 contract.clearValues("totalBaseAmount").add(totalBaseAmount); 499 contract.clearValues("totalDiscountAmount").add(totalDiscountAmount); 500 contract.clearValues("totalAmount").add(totalAmount); 501 contract.clearValues("totalTaxAmount").add(totalTaxAmount); 502 contract.clearValues("totalAmountIncludingTax").add(totalAmount.add(totalTaxAmount)); 503 contract.clearValues("totalSalesCommission").add(totalSalesCommission); 504 } 505 } 506 } 507 508 516 void calculateForwardReferences( 517 DataproviderObject_1_0 contract, 518 Set fetchSet 519 ) throws ServiceException { 520 String contractType = (String )contract.values(SystemAttributes.OBJECT_CLASS).get(0); 521 String referenceName = null; 522 if("org:opencrx:kernel:contract1:Lead".equals(contractType)) { 523 referenceName = "opportunity"; 524 } 525 else if("org:opencrx:kernel:contract1:Opportunity".equals(contractType)) { 526 referenceName = "quote"; 527 } 528 else if("org:opencrx:kernel:contract1:Quote".equals(contractType)) { 529 referenceName = "salesOrder"; 530 } 531 else if("org:opencrx:kernel:contract1:SalesOrder".equals(contractType)) { 532 referenceName = "invoice"; 533 } 534 if( 535 (referenceName != null) && 536 ((fetchSet == null) || fetchSet.contains(referenceName)) 537 ) { 538 Path contractIdentity = new Path((String )contract.values(SystemAttributes.OBJECT_IDENTITY).get(0)); 539 List referencedContracts = 540 this.delegation.addFindRequest( 541 contractIdentity.getParent().getParent().getChild(referenceName), 542 new FilterProperty[]{ 543 new FilterProperty( 544 Quantors.THERE_EXISTS, 545 "origin", 546 FilterOperators.IS_IN, 547 new Object []{ 548 contractIdentity 549 } 550 ) 551 } 552 ); 553 contract.clearValues(referenceName); 554 for(Iterator i = referencedContracts.iterator(); i.hasNext(); ) { 555 contract.values(referenceName).add( 556 ((DataproviderObject_1_0)i.next()).path() 557 ); 558 } 559 } 560 } 561 562 DataproviderObject createInvoice( 564 ServiceHeader header, 565 DataproviderObject_1_0 source 566 ) throws ServiceException { 567 Map objectMarshallers = new HashMap (); 568 objectMarshallers.put( 569 "org:opencrx:kernel:contract1:SalesOrder", 570 new Marshaller() { 571 public Object marshal(Object s) throws ServiceException { 572 DataproviderObject_1_0 salesOrder = (DataproviderObject_1_0)s; 573 DataproviderObject invoice = new DataproviderObject(new Path("")); 574 copyAbstractContract( 575 salesOrder, 576 invoice 577 ); 578 invoice.clearValues(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:Invoice"); 579 invoice.clearValues("contractState").add(new Short ((short)0)); 580 return invoice; 581 } 582 public Object unmarshal(Object s) { 583 throw new UnsupportedOperationException (); 584 } 585 } 586 ); 587 objectMarshallers.put( 588 "org:opencrx:kernel:contract1:SalesOrderPosition", 589 new Marshaller() { 590 public Object marshal(Object s) throws ServiceException { 591 DataproviderObject_1_0 salesOrderPosition = (DataproviderObject_1_0)s; 592 DataproviderObject invoicePosition = new DataproviderObject(new Path("")); 593 copyAbstractContractPosition( 594 salesOrderPosition, 595 invoicePosition 596 ); 597 invoicePosition.clearValues(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:InvoicePosition"); 598 invoicePosition.clearValues("contractPositionState").add(new Short ((short)0)); 599 return invoicePosition; 600 } 601 public Object unmarshal(Object s) { 602 throw new UnsupportedOperationException (); 603 } 604 } 605 ); 606 objectMarshallers.put( 607 "org:opencrx:kernel:contract1:SalesOrderBundledProductPosition", 608 new Marshaller() { 609 public Object marshal(Object s) throws ServiceException { 610 DataproviderObject_1_0 salesOrderPosition = (DataproviderObject_1_0)s; 611 DataproviderObject invoicePosition = new DataproviderObject(new Path("")); 612 copyAbstractContractPosition( 613 salesOrderPosition, 614 invoicePosition 615 ); 616 invoicePosition.clearValues(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:InvoiceBundledProductPosition"); 617 invoicePosition.clearValues("contractPositionState").add(new Short ((short)0)); 618 return invoicePosition; 619 } 620 public Object unmarshal(Object s) { 621 throw new UnsupportedOperationException (); 622 } 623 } 624 ); 625 objectMarshallers.put( 626 "org:opencrx:kernel:contract1:SalesOrderProductBundlePosition", 627 new Marshaller() { 628 public Object marshal(Object s) throws ServiceException { 629 DataproviderObject_1_0 salesOrderPosition = (DataproviderObject_1_0)s; 630 DataproviderObject invoicePosition = new DataproviderObject(new Path("")); 631 copyAbstractContractPosition( 632 salesOrderPosition, 633 invoicePosition 634 ); 635 invoicePosition.clearValues(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:InvoiceProductBundlePosition"); 636 invoicePosition.clearValues("contractPositionState").add(new Short ((short)0)); 637 return invoicePosition; 638 } 639 public Object unmarshal(Object s) { 640 throw new UnsupportedOperationException (); 641 } 642 } 643 ); 644 objectMarshallers.put( 645 "org:opencrx:kernel:contract1:SalesOrderProductOfferingPosition", 646 new Marshaller() { 647 public Object marshal(Object s) throws ServiceException { 648 DataproviderObject_1_0 salesOrderPosition = (DataproviderObject_1_0)s; 649 DataproviderObject invoicePosition = new DataproviderObject(new Path("")); 650 copyAbstractContractPosition( 651 salesOrderPosition, 652 invoicePosition 653 ); 654 invoicePosition.clearValues(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:InvoiceProductOfferingPosition"); 655 invoicePosition.clearValues("contractPositionState").add(new Short ((short)0)); 656 return invoicePosition; 657 } 658 public Object unmarshal(Object s) { 659 throw new UnsupportedOperationException (); 660 } 661 } 662 ); 663 DataproviderObject invoice = 664 this.plugin.retrieveObjectForModification( 665 this.cloning.cloneAndUpdateReferences( 666 header, 667 source, 668 source.path().getParent().getParent().getChild("invoice"), 669 objectMarshallers, 670 DEFAULT_REFERENCE_FILTER, 671 false 672 ).path() 673 ); 674 invoice.clearValues("origin").add(source.path()); 675 if(invoice.values("salesRep").size() == 0) { 676 this.plugin.assignToMe( 677 header, 678 invoice, 679 null, 680 true, 681 null 682 ); 683 } 684 return invoice; 685 } 686 687 DataproviderObject createSalesOrder( 689 ServiceHeader header, 690 DataproviderObject_1_0 source 691 ) throws ServiceException { 692 Map objectMarshallers = new HashMap (); 693 objectMarshallers.put( 694 "org:opencrx:kernel:contract1:Quote", 695 new Marshaller() { 696 public Object marshal(Object s) throws ServiceException { 697 DataproviderObject_1_0 quote = (DataproviderObject_1_0)s; 698 DataproviderObject salesOrder = new DataproviderObject(new Path("")); 699 copyAbstractContract( 700 quote, 701 salesOrder 702 ); 703 salesOrder.clearValues(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:SalesOrder"); 704 salesOrder.clearValues("contractState").add(new Short ((short)0)); 705 return salesOrder; 706 } 707 public Object unmarshal(Object s) { 708 throw new UnsupportedOperationException (); 709 } 710 } 711 ); 712 objectMarshallers.put( 713 "org:opencrx:kernel:contract1:QuotePosition", 714 new Marshaller() { 715 public Object marshal(Object s) throws ServiceException { 716 DataproviderObject_1_0 quotePosition = (DataproviderObject_1_0)s; 717 DataproviderObject salesOrderPosition = new DataproviderObject(new Path("")); 718 copyAbstractContractPosition( 719 quotePosition, 720 salesOrderPosition 721 ); 722 salesOrderPosition.clearValues(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:SalesOrderPosition"); 723 salesOrderPosition.clearValues("contractPositionState").add(new Short ((short)0)); 724 return salesOrderPosition; 725 } 726 public Object unmarshal(Object s) { 727 throw new UnsupportedOperationException (); 728 } 729 } 730 ); 731 objectMarshallers.put( 732 "org:opencrx:kernel:contract1:QuoteBundledProductPosition", 733 new Marshaller() { 734 public Object marshal(Object s) throws ServiceException { 735 DataproviderObject_1_0 quotePosition = (DataproviderObject_1_0)s; 736 DataproviderObject salesOrderPosition = new DataproviderObject(new Path("")); 737 copyAbstractContractPosition( 738 quotePosition, 739 salesOrderPosition 740 ); 741 salesOrderPosition.clearValues(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:SalesOrderBundledProductPosition"); 742 salesOrderPosition.clearValues("contractPositionState").add(new Short ((short)0)); 743 return salesOrderPosition; 744 } 745 public Object unmarshal(Object s) { 746 throw new UnsupportedOperationException (); 747 } 748 } 749 ); 750 objectMarshallers.put( 751 "org:opencrx:kernel:contract1:QuoteProductBundlePosition", 752 new Marshaller() { 753 public Object marshal(Object s) throws ServiceException { 754 DataproviderObject_1_0 quotePosition = (DataproviderObject_1_0)s; 755 DataproviderObject salesOrderPosition = new DataproviderObject(new Path("")); 756 copyAbstractContractPosition( 757 quotePosition, 758 salesOrderPosition 759 ); 760 salesOrderPosition.clearValues(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:SalesOrderProductBundlePosition"); 761 salesOrderPosition.clearValues("contractPositionState").add(new Short ((short)0)); 762 return salesOrderPosition; 763 } 764 public Object unmarshal(Object s) { 765 throw new UnsupportedOperationException (); 766 } 767 } 768 ); 769 objectMarshallers.put( 770 "org:opencrx:kernel:contract1:QuoteProductOfferingPosition", 771 new Marshaller() { 772 public Object marshal(Object s) throws ServiceException { 773 DataproviderObject_1_0 quotePosition = (DataproviderObject_1_0)s; 774 DataproviderObject salesOrderPosition = new DataproviderObject(new Path("")); 775 copyAbstractContractPosition( 776 quotePosition, 777 salesOrderPosition 778 ); 779 salesOrderPosition.clearValues(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:SalesOrderProductOfferingPosition"); 780 salesOrderPosition.clearValues("contractPositionState").add(new Short ((short)0)); 781 return salesOrderPosition; 782 } 783 public Object unmarshal(Object s) { 784 throw new UnsupportedOperationException (); 785 } 786 } 787 ); 788 DataproviderObject salesOrder = 789 this.plugin.retrieveObjectForModification( 790 this.cloning.cloneAndUpdateReferences( 791 header, 792 source, 793 source.path().getParent().getParent().getChild("salesOrder"), 794 objectMarshallers, 795 DEFAULT_REFERENCE_FILTER, 796 false 797 ).path() 798 ); 799 salesOrder.clearValues("origin").add(source.path()); 800 if(salesOrder.values("salesRep").size() == 0) { 801 this.plugin.assignToMe( 802 header, 803 salesOrder, 804 null, 805 true, 806 null 807 ); 808 } 809 return salesOrder; 810 } 811 812 DataproviderObject createQuote( 814 ServiceHeader header, 815 DataproviderObject_1_0 source 816 ) throws ServiceException { 817 Map objectMarshallers = new HashMap (); 818 objectMarshallers.put( 819 "org:opencrx:kernel:contract1:Opportunity", 820 new Marshaller() { 821 public Object marshal(Object s) throws ServiceException { 822 DataproviderObject_1_0 opportunity = (DataproviderObject_1_0)s; 823 DataproviderObject quote = new DataproviderObject(new Path("")); 824 copyAbstractContract( 825 opportunity, 826 quote 827 ); 828 quote.clearValues(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:Quote"); 829 quote.clearValues("contractState").add(new Short ((short)0)); 830 return quote; 831 } 832 public Object unmarshal(Object s) { 833 throw new UnsupportedOperationException (); 834 } 835 } 836 ); 837 objectMarshallers.put( 838 "org:opencrx:kernel:contract1:OpportunityPosition", 839 new Marshaller() { 840 public Object marshal(Object s) throws ServiceException { 841 DataproviderObject_1_0 opportunityPosition = (DataproviderObject_1_0)s; 842 DataproviderObject quotePosition = new DataproviderObject(new Path("")); 843 copyAbstractContractPosition( 844 opportunityPosition, 845 quotePosition 846 ); 847 quotePosition.clearValues(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:QuotePosition"); 848 quotePosition.clearValues("contractPositionState").add(new Short ((short)0)); 849 return quotePosition; 850 } 851 public Object unmarshal(Object s) { 852 throw new UnsupportedOperationException (); 853 } 854 } 855 ); 856 objectMarshallers.put( 857 "org:opencrx:kernel:contract1:OpportunityBundledProductPosition", 858 new Marshaller() { 859 public Object marshal(Object s) throws ServiceException { 860 DataproviderObject_1_0 opportunityPosition = (DataproviderObject_1_0)s; 861 DataproviderObject quotePosition = new DataproviderObject(new Path("")); 862 copyAbstractContractPosition( 863 opportunityPosition, 864 quotePosition 865 ); 866 quotePosition.clearValues(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:QuoteBundledProductPosition"); 867 quotePosition.clearValues("contractPositionState").add(new Short ((short)0)); 868 return quotePosition; 869 } 870 public Object unmarshal(Object s) { 871 throw new UnsupportedOperationException (); 872 } 873 } 874 ); 875 objectMarshallers.put( 876 "org:opencrx:kernel:contract1:OpportunityProductBundlePosition", 877 new Marshaller() { 878 public Object marshal(Object s) throws ServiceException { 879 DataproviderObject_1_0 opportunityPosition = (DataproviderObject_1_0)s; 880 DataproviderObject quotePosition = new DataproviderObject(new Path("")); 881 copyAbstractContractPosition( 882 opportunityPosition, 883 quotePosition 884 ); 885 quotePosition.clearValues(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:QuoteProductBundlePosition"); 886 quotePosition.clearValues("contractPositionState").add(new Short ((short)0)); 887 return quotePosition; 888 } 889 public Object unmarshal(Object s) { 890 throw new UnsupportedOperationException (); 891 } 892 } 893 ); 894 objectMarshallers.put( 895 "org:opencrx:kernel:contract1:OpportunityProductOfferingPosition", 896 new Marshaller() { 897 public Object marshal(Object s) throws ServiceException { 898 DataproviderObject_1_0 opportunityPosition = (DataproviderObject_1_0)s; 899 DataproviderObject quotePosition = new DataproviderObject(new Path("")); 900 copyAbstractContractPosition( 901 opportunityPosition, 902 quotePosition 903 ); 904 quotePosition.clearValues(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:QuoteProductOfferingPosition"); 905 quotePosition.clearValues("contractPositionState").add(new Short ((short)0)); 906 return quotePosition; 907 } 908 public Object unmarshal(Object s) { 909 throw new UnsupportedOperationException (); 910 } 911 } 912 ); 913 DataproviderObject quote = 914 this.plugin.retrieveObjectForModification( 915 this.cloning.cloneAndUpdateReferences( 916 header, 917 source, 918 source.path().getParent().getParent().getChild("quote"), 919 objectMarshallers, 920 DEFAULT_REFERENCE_FILTER, 921 false 922 ).path() 923 ); 924 quote.clearValues("origin").add(source.path()); 925 if(quote.values("salesRep").size() == 0) { 926 this.plugin.assignToMe( 927 header, 928 quote, 929 null, 930 true, 931 null 932 ); 933 } 934 return quote; 935 } 936 937 DataproviderObject createOpportunity( 939 ServiceHeader header, 940 DataproviderObject_1_0 source 941 ) throws ServiceException { 942 Map objectMarshallers = new HashMap (); 943 objectMarshallers.put( 944 "org:opencrx:kernel:contract1:Lead", 945 new Marshaller() { 946 public Object marshal(Object s) throws ServiceException { 947 DataproviderObject_1_0 lead = (DataproviderObject_1_0)s; 948 DataproviderObject opportunity = new DataproviderObject(new Path("")); 949 copyAbstractContract( 950 lead, 951 opportunity 952 ); 953 opportunity.clearValues(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:Opportunity"); 954 opportunity.clearValues("contractState").add(new Short ((short)0)); 955 return opportunity; 956 } 957 public Object unmarshal(Object s) { 958 throw new UnsupportedOperationException (); 959 } 960 } 961 ); 962 DataproviderObject opportunity = 963 this.plugin.retrieveObjectForModification( 964 this.cloning.cloneAndUpdateReferences( 965 header, 966 source, 967 source.path().getParent().getParent().getChild("opportunity"), 968 objectMarshallers, 969 DEFAULT_REFERENCE_FILTER, 970 false 971 ).path() 972 ); 973 opportunity.clearValues("origin").add(source.path()); 974 if(opportunity.values("salesRep").size() == 0) { 975 this.plugin.assignToMe( 976 header, 977 opportunity, 978 null, 979 true, 980 null 981 ); 982 } 983 return opportunity; 984 } 985 986 public boolean updateContractPositionPrice( 988 DataproviderObject_1_0 contract, 989 DataproviderObject position, 990 DataproviderObject_1_0 oldValues, 991 DataproviderObject_1_0 product, 992 boolean priceEnabledOverridesPosition 993 ) throws ServiceException { 994 995 if(contract == null) return false; 996 if(position == null) return false; 997 if(product == null) return false; 998 Path productIdentity = product.path(); 999 1000 Path pricingRuleIdentity = null; 1002 if(oldValues == null) { 1003 pricingRuleIdentity = (Path)position.values("pricingRule").get(0); 1004 } 1005 else { 1006 pricingRuleIdentity = (position.getValues("pricingRule") != null) && (position.values("pricingRule").size() > 0) 1007 ? (Path)position.values("pricingRule").get(0) 1008 : (Path)oldValues.values("pricingRule").get(0); 1009 } 1010 if(pricingRuleIdentity == null) return false; 1011 BigDecimal quantity = null; 1013 if(oldValues == null) { 1014 quantity = (BigDecimal )position.values("quantity").get(0); 1015 } 1016 else { 1017 quantity = (position.getValues("quantity") != null) && (position.values("quantity").size() > 0) 1018 ? (BigDecimal )position.values("quantity").get(0) 1019 : (BigDecimal )oldValues.values("quantity").get(0); 1020 } 1021 if(quantity == null) return false; 1022 String pricingDate = null; 1024 if(oldValues == null) { 1025 pricingDate = (String )position.values("pricingDate").get(0); 1026 } 1027 else { 1028 pricingDate = (position.getValues("pricingDate") != null) && (position.values("pricingDate").size() > 0) 1029 ? (String )position.values("pricingDate").get(0) 1030 : (String )oldValues.values("pricingDate").get(0); 1031 } 1032 Path priceUomIdentity = (position.getValues("priceUom") != null) && (position.values("priceUom").size() > 0) 1034 ? (Path)position.values("priceUom").get(0) 1035 : position.values("uom").size() > 0 1036 ? (Path)position.values("uom").get(0) 1037 : oldValues.values("priceUom").size() > 0 1038 ? (Path)oldValues.values("priceUom").get(0) 1039 : (Path)oldValues.values("uom").get(0); 1040 Path priceLevelIdentity = null; 1042 if(position.getValues("priceLevel") != null) { 1043 priceLevelIdentity = (Path)position.values("priceLevel").get(0); 1044 } 1045 else { 1046 try { 1047 org.opencrx.kernel.product1.cci.GetPriceLevelResult res = 1048 this.plugin.products.getPriceLevel( 1049 pricingRuleIdentity == null 1050 ? null 1051 : (org.opencrx.kernel.product1.cci.PricingRule)this.rootPkg.refObject(pricingRuleIdentity.toXri()), 1052 (org.opencrx.kernel.contract1.cci.AbstractContract)this.rootPkg.refObject(contract.path().toXri()), 1053 productIdentity == null 1054 ? null 1055 : (org.opencrx.kernel.product1.cci.AbstractProduct)this.rootPkg.refObject(productIdentity.toXri()), 1056 priceUomIdentity == null 1057 ? null 1058 : (org.opencrx.kernel.uom1.cci.Uom)this.rootPkg.refObject(priceUomIdentity.toXri()), 1059 quantity, 1060 pricingDate == null 1061 ? new Date () 1062 : org.openmdx.base.text.format.DateFormat.getInstance().parse(pricingDate) 1063 ); 1064 priceLevelIdentity = (Path)res.refDelegate().objGetValue("priceLevel"); 1065 } 1066 catch(ParseException e) { 1067 throw new ServiceException(e); 1068 } 1069 } 1070 position.clearValues("priceLevel"); 1071 if(priceLevelIdentity != null) { 1072 position.values("priceLevel").add(priceLevelIdentity); 1073 } 1074 List prices = new ArrayList (); 1076 DataproviderObject_1_0 listPrice = null; 1077 if(priceLevelIdentity != null) { 1078 prices = this.delegation.addFindRequest( 1081 productIdentity.getChild("basePrice"), 1082 new FilterProperty[]{ 1083 new FilterProperty( 1084 Quantors.THERE_EXISTS, 1085 "priceLevel", 1086 FilterOperators.IS_IN, 1087 new Object []{priceLevelIdentity} 1088 ), 1089 new FilterProperty( 1090 Quantors.THERE_EXISTS, 1091 "uom", 1092 FilterOperators.IS_IN, 1093 new Object []{priceUomIdentity} 1094 ) 1095 }, 1096 AttributeSelectors.ALL_ATTRIBUTES, 1097 0, 1098 Integer.MAX_VALUE, 1099 Directions.ASCENDING 1100 ); 1101 for( 1103 Iterator i = prices.iterator(); 1104 i.hasNext(); 1105 ) { 1106 DataproviderObject_1_0 current = (DataproviderObject_1_0)i.next(); 1107 boolean quantityFromMatches = 1108 (current.values("quantityFrom").size() == 0) || 1109 (quantity == null) || 1110 ((BigDecimal )current.values("quantityFrom").get(0)).compareTo(quantity) >= 0; 1111 boolean quantityToMatches = 1112 (current.values("quantityTo").size() == 0) || 1113 (quantity == null) || 1114 ((BigDecimal )current.values("quantityTo").get(0)).compareTo(quantity) < 0; 1115 if(quantityFromMatches && quantityToMatches) { 1116 listPrice = current; 1117 break; 1118 } 1119 } 1120 } 1121 if(listPrice != null) { 1123 position.clearValues("listPrice").add( 1124 listPrice.path() 1125 ); 1126 position.clearValues("pricingState").add( 1127 new Short (PRICING_STATE_OK) 1128 ); 1129 if(oldValues == null) { 1131 if(position.getValues("pricePerUnit") == null) { 1132 position.values("pricePerUnit").addAll( 1133 listPrice.values("price") 1134 ); 1135 position.clearValues("discount").addAll( 1136 listPrice.values("discount") 1137 ); 1138 position.clearValues("discountIsPercentage").addAll( 1139 listPrice.values("discountIsPercentage") 1140 ); 1141 } 1142 if(position.getValues("priceUom") == null) { 1143 position.values("priceUom").addAll(listPrice.values("uom")); 1144 } 1145 } 1146 else { 1148 boolean pricePerUnitModified = (position.getValues("pricePerUnit") != null) && (position.getValues("pricePerUnit").size() > 0) && (oldValues.getValues("pricePerUnit").size() > 0) 1149 ? ((BigDecimal )position.getValues("pricePerUnit").get(0)).compareTo((BigDecimal )oldValues.values("pricePerUnit").get(0)) != 0 1150 : position.getValues("pricePerUnit").size() > 0; 1151 boolean priceUomModified = (position.getValues("priceUom") != null) && (position.getValues("priceUom").size() > 0) && (oldValues.getValues("priceUom").size() > 0) 1152 ? position.getValues("priceUom").get(0).equals(oldValues.values("priceUom").get(0)) 1153 : position.getValues("priceUom").size() > 0; 1154 if(priceEnabledOverridesPosition && !pricePerUnitModified) { 1155 position.clearValues("pricePerUnit").addAll( 1156 listPrice.values("price") 1157 ); 1158 position.clearValues("discount").addAll( 1159 listPrice.values("discount") 1160 ); 1161 position.clearValues("discountIsPercentage").addAll( 1162 listPrice.values("discountIsPercentage") 1163 ); 1164 } 1165 if(priceEnabledOverridesPosition && !priceUomModified) { 1166 position.clearValues("priceUom").addAll(listPrice.values("uom")); 1167 } 1168 } 1169 } 1170 return listPrice != null; 1171 } 1172 1173 public int getMaxLineItemNumber( 1175 DataproviderObject_1_0 contract, 1176 Path parentPositionIdentity 1177 ) throws ServiceException { 1178 int maxLineItemNumber = 0; 1179 List positions = this.delegation.addFindRequest( 1180 contract.path().getChild("position"), 1181 parentPositionIdentity == null 1182 ? null 1183 : new FilterProperty[]{ 1184 new FilterProperty( 1185 Quantors.THERE_EXISTS, 1186 "parentPosition", 1187 FilterOperators.IS_IN, 1188 new Path[]{parentPositionIdentity} 1189 ) 1190 }, 1191 AttributeSelectors.ALL_ATTRIBUTES, 1192 0, 1193 Integer.MAX_VALUE, 1194 Directions.ASCENDING 1195 ); 1196 for( 1197 Iterator i = positions.iterator(); 1198 i.hasNext(); 1199 ) { 1200 DataproviderObject_1_0 pos = (DataproviderObject_1_0)i.next(); 1201 if( 1202 (pos.values("lineItemNumber").size() > 0) && 1203 (((Number )pos.values("lineItemNumber").get(0)).intValue() > maxLineItemNumber) 1204 ) { 1205 maxLineItemNumber = ((Number )pos.values("lineItemNumber").get(0)).intValue(); 1206 } 1207 } 1208 return maxLineItemNumber; 1209 } 1210 1211 public void updateContractPosition( 1213 ServiceHeader header, 1214 DataproviderObject_1_0 contract, 1215 DataproviderObject position, 1216 DataproviderObject_1_0 oldValues, 1217 DataproviderObject_1_0 product, 1218 boolean reprice 1219 ) { 1220 try { 1221 1222 Path positionUomIdentity = null; 1224 Path priceUomIdentity = null; 1225 if(oldValues == null) { 1227 positionUomIdentity = (position.getValues("uom") != null) && (position.values("uom").size() > 0) 1229 ? (Path)position.values("uom").get(0) 1230 : (product != null) && (product.values("defaultUom").size() > 0) 1231 ? (Path)product.values("defaultUom").get(0) 1232 : null; 1233 priceUomIdentity = (position.getValues("priceUom") != null) && (position.values("priceUom").size() > 0) 1234 ? (Path)position.values("priceUom").get(0) 1235 : null; 1236 } 1237 else { 1239 positionUomIdentity = position.getValues("uom") != null 1241 ? (Path)position.values("uom").get(0) 1242 : (Path)oldValues.values("uom").get(0); 1243 priceUomIdentity = position.getValues("priceUom") != null 1244 ? (Path)position.values("priceUom").get(0) 1245 : (Path)oldValues.values("priceUom").get(0); 1246 } 1247 if(position.getValues("uom") != null) { 1249 position.clearValues("uom"); 1250 } 1251 if(positionUomIdentity != null) { 1252 position.values("uom").add(positionUomIdentity); 1253 } 1254 if(position.getValues("priceUom") != null) { 1256 position.clearValues("priceUom"); 1257 } 1258 if(priceUomIdentity != null) { 1259 position.values("priceUom").add(priceUomIdentity); 1260 } 1261 1262 Path salesTaxTypeIdentity = null; 1264 if(oldValues == null) { 1266 salesTaxTypeIdentity = (position.getValues("salesTaxType") != null) && (position.values("salesTaxType").size() > 0) 1268 ? (Path)position.values("salesTaxType").get(0) 1269 : (product != null) && (product.values("salesTaxType").size() > 0) 1270 ? (Path)product.values("salesTaxType").get(0) 1271 : null; 1272 } 1273 else { 1275 salesTaxTypeIdentity = position.getValues("salesTaxType") != null 1276 ? (Path)position.values("salesTaxType").get(0) 1277 : (Path)oldValues.values("salesTaxType").get(0); 1278 } 1279 position.clearValues("salesTaxType"); 1280 if(salesTaxTypeIdentity != null) { 1281 position.values("salesTaxType").add(salesTaxTypeIdentity); 1282 } 1283 1284 Path pricingRuleIdentity = null; 1286 if(oldValues == null) { 1288 pricingRuleIdentity = (position.getValues("pricingRule") != null) && (position.values("pricingRule").size() > 0) 1289 ? (Path)position.values("pricingRule").get(0) 1290 : (Path)contract.values("pricingRule").get(0); 1291 if(pricingRuleIdentity == null) { 1292 List pricingRules = this.delegation.addFindRequest( 1294 product.path().getPrefix(5).getChild("pricingRule"), 1295 new FilterProperty[]{ 1296 new FilterProperty( 1297 Quantors.THERE_EXISTS, 1298 "isDefault", 1299 FilterOperators.IS_IN, 1300 new Object []{Boolean.TRUE} 1301 ) 1302 } 1303 ); 1304 if(pricingRules.size() > 0) { 1305 pricingRuleIdentity = ((DataproviderObject_1_0)pricingRules.iterator().next()).path(); 1306 } 1307 } 1308 } 1309 else { 1311 pricingRuleIdentity = position.getValues("pricingRule") != null 1312 ? (Path)position.values("pricingRule").get(0) 1313 : (Path)oldValues.values("pricingRule").get(0); 1314 } 1315 position.clearValues("pricingRule"); 1316 if(pricingRuleIdentity != null) { 1317 position.values("pricingRule").add(pricingRuleIdentity); 1318 } 1319 if(reprice) { 1321 this.updateContractPositionPrice( 1322 contract, 1323 position, 1324 oldValues, 1325 product, 1326 true 1327 ); 1328 } 1329 } 1330 catch(ServiceException e) { 1331 AppLog.info(e.getMessage(), e.getCause(), 1); 1332 } 1333 } 1334 1335 public DataproviderObject createContractPosition( 1337 ServiceHeader header, 1338 DataproviderObject_1_0 contract, 1339 DataproviderObject param 1340 ) { 1341 DataproviderObject position = null; 1342 try { 1343 position = new DataproviderObject( 1344 contract.path().getDescendant(new String []{"position", this.plugin.getUidAsString()}) 1345 ); 1346 String contractType = (String )contract.values(SystemAttributes.OBJECT_CLASS).get(0); 1347 if("org:opencrx:kernel:contract1:Opportunity".equals(contractType)) { 1348 position.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:OpportunityPosition"); 1349 } 1350 else if("org:opencrx:kernel:contract1:Quote".equals(contractType)) { 1351 position.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:QuotePosition"); 1352 } 1353 else if("org:opencrx:kernel:contract1:SalesOrder".equals(contractType)) { 1354 position.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:SalesOrderPosition"); 1355 } 1356 else if("org:opencrx:kernel:contract1:Invoice".equals(contractType)) { 1357 position.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:InvoicePosition"); 1358 } 1359 else { 1360 return null; 1361 } 1362 1363 position.values("lineItemNumber").add( 1365 new Integer ( 1366 100000 * (this.getMaxLineItemNumber(contract, null) / 100000 + 1) 1367 ) 1368 ); 1369 if(param.values("name").size() > 0) { 1371 position.values("name").addAll(param.values("name")); 1372 } 1373 else { 1374 position.values("name").add("Position " + position.values("lineItemNumber").get(0)); 1375 } 1376 if(param.values("quantity").size() > 0) { 1378 position.values("quantity").addAll(param.values("quantity")); 1379 } 1380 else { 1381 position.values("quantity").add(new BigDecimal (1)); 1382 } 1383 if(param.values("pricingDate").size() > 0) { 1385 position.values("pricingDate").addAll(param.values("pricingDate")); 1386 } 1387 else { 1388 position.values("pricingDate").add( 1389 contract.values("pricingDate").size() > 0 1390 ? contract.values("pricingDate").get(0) 1391 : org.openmdx.base.text.format.DateFormat.getInstance().format(new Date ()) 1392 ); 1393 } 1394 Path productIdentity = (Path)param.values("product").get(0); 1396 DataproviderObject_1_0 product = productIdentity == null 1397 ? null 1398 : this.plugin.retrieveObjectFromDelegation(productIdentity); 1399 if(param.values("uom").size() > 0) { 1401 position.values("uom").addAll( 1402 param.values("uom") 1403 ); 1404 } 1405 if(param.values("priceUom").size() > 0) { 1407 position.values("priceUom").addAll( 1408 param.values("priceUom") 1409 ); 1410 } 1411 if(param.values("pricingRule").size() > 0) { 1413 position.values("pricingRule").addAll( 1414 param.values("pricingRule") 1415 ); 1416 } 1417 this.updateContractPosition( 1419 header, 1420 contract, 1421 position, 1422 null, 1423 product, 1424 true 1425 ); 1426 position.clearValues("product"); 1427 if(productIdentity != null) { 1428 position.values("product").add(productIdentity); 1429 } 1430 1431 this.delegation.addCreateRequest( 1433 position 1434 ); 1435 this.plugin.products.cloneProductConfigurationSet( 1437 header, 1438 productIdentity, 1439 position.path(), 1440 false, 1441 true 1442 ); 1443 } 1444 catch(ServiceException e) { 1445 AppLog.info(e.getMessage(), e.getCause(), 1); 1446 } 1447 return position; 1448 } 1449 1450 private int calculateTimeDistributionOpenContracts( 1452 ServiceHeader header, 1453 Path reference, 1454 String objectClass, 1455 int[] timeDistribution, 1456 String distributionOnAttribute, 1457 int closedThreshold 1458 ) { 1459 try { 1460 List objects = this.delegation.addFindRequest( 1461 reference, 1462 new FilterProperty[]{ 1463 new FilterProperty( 1464 Quantors.THERE_EXISTS, 1465 SystemAttributes.OBJECT_CLASS, 1466 FilterOperators.IS_IN, 1467 new String []{objectClass} 1468 ), 1469 new FilterProperty( 1470 Quantors.THERE_EXISTS, 1471 "contractState", 1472 FilterOperators.IS_LESS, 1473 new Number []{new Short ((short)closedThreshold)} 1474 ) 1475 }, 1476 AttributeSelectors.ALL_ATTRIBUTES, 1477 0, 1478 Contracts.BATCHING_MODE_SIZE, 1479 Directions.ASCENDING 1480 ); 1481 int count = 0; 1482 for(Iterator i = objects.iterator(); i.hasNext(); ) { 1483 DataproviderObject_1_0 object = (DataproviderObject_1_0)i.next(); 1484 Date dt = new Date (); 1485 try { 1486 dt = org.openmdx.base.text.format.DateFormat.getInstance().parse( 1487 (String )object.values(distributionOnAttribute).get(0) 1488 ); 1489 } catch(Exception e) {} 1490 1491 long delayInDays = (System.currentTimeMillis() - dt.getTime()) / 86400000; 1492 if(delayInDays < 0) timeDistribution[0]++; 1493 else if(delayInDays < 1) timeDistribution[1]++; 1494 else if(delayInDays < 2) timeDistribution[2]++; 1495 else if(delayInDays < 3) timeDistribution[3]++; 1496 else if(delayInDays < 4) timeDistribution[4]++; 1497 else if(delayInDays < 5) timeDistribution[5]++; 1498 else if(delayInDays < 6) timeDistribution[6]++; 1499 else if(delayInDays < 7) timeDistribution[7]++; 1500 else if(delayInDays < 8) timeDistribution[8]++; 1501 else if(delayInDays < 15) timeDistribution[9]++; 1502 else if(delayInDays < 31) timeDistribution[10]++; 1503 else if(delayInDays < 91) timeDistribution[11]++; 1504 else if(delayInDays < 181) timeDistribution[12]++; 1505 else if(delayInDays < 361) timeDistribution[13]++; 1506 else timeDistribution[14]++; 1507 1508 count++; 1509 } 1510 return count; 1511 } 1512 catch(ServiceException e) { 1513 return 0; 1514 } 1515 } 1516 1517 DataproviderObject[] calculateUserHomeCharts( 1519 ServiceHeader header, 1520 Path userHome, 1521 Path chartReference 1522 ) throws ServiceException { 1523 1524 DateFormat dateFormat = 1525 DateFormat.getDateInstance(DateFormat.SHORT, new Locale ("en_US")); 1526 DateFormat timeFormat = 1527 DateFormat.getTimeInstance(DateFormat.SHORT, new Locale ("en_US")); 1528 String createdAt = dateFormat.format(new Date ()) + " " + timeFormat.format(new Date ()); 1529 1530 String fullName = ""; 1532 try { 1533 fullName = (String )this.plugin.retrieveObjectFromLocal( 1534 header, 1535 (Path)this.plugin.retrieveObjectFromLocal(header, userHome).values("contact").get(0) 1536 ).values("fullName").get(0); 1537 } catch(Exception e) {} 1538 1539 DataproviderObject[] charts = new DataproviderObject[2]; 1540 String chartTitle = null; 1541 1542 1545 chartTitle = (fullName.length() == 0 ? "" : fullName + ": ") + "Assigned Open Contracts Overview (" + createdAt + ")"; 1546 1547 charts[0] = new DataproviderObject( 1548 chartReference.getChild("0") 1549 ); 1550 charts[0].values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:home1:Chart"); 1551 charts[0].values("description").add(chartTitle); 1552 ByteArrayOutputStream os = new ByteArrayOutputStream (); 1553 PrintWriter pw = new PrintWriter (os); 1554 1555 pw.println("BEGIN:VND.OPENDMDX-CHART"); 1556 pw.println("VERSION:1.0"); 1557 pw.println("COUNT:1"); 1558 1559 pw.println("CHART[0].TYPE:HORIZBAR"); 1561 pw.println("CHART[0].LABEL:" + chartTitle); 1562 pw.println("CHART[0].SCALEXTITLE:#Contracts"); 1563 pw.println("CHART[0].SCALEYTITLE:Contract type"); 1564 pw.println("CHART[0].COUNT:5"); 1565 1566 pw.println("CHART[0].LABEL[0]:Invoices"); 1567 pw.println("CHART[0].LABEL[1]:Sales Orders"); 1568 pw.println("CHART[0].LABEL[2]:Quotes"); 1569 pw.println("CHART[0].LABEL[3]:Opportunities"); 1570 pw.println("CHART[0].LABEL[4]:Leads"); 1571 1572 int[] counts = new int[]{0, 0, 0, 0, 0}; 1573 int[] timeDistribution = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 1574 Path assignedContractReference = userHome.getChild("assignedContract"); 1575 counts[0] = this.calculateTimeDistributionOpenContracts( 1576 header, 1577 assignedContractReference, 1578 "org:opencrx:kernel:contract1:Invoice", 1579 timeDistribution, 1580 SystemAttributes.MODIFIED_AT, 1581 CLOSED_THRESHOLD_INVOICE 1582 ); 1583 counts[1] = this.calculateTimeDistributionOpenContracts( 1584 header, 1585 assignedContractReference, 1586 "org:opencrx:kernel:contract1:SalesOrder", 1587 timeDistribution, 1588 SystemAttributes.MODIFIED_AT, 1589 CLOSED_THRESHOLD_SALES_ORDER 1590 ); 1591 counts[2] = this.calculateTimeDistributionOpenContracts( 1592 header, 1593 assignedContractReference, 1594 "org:opencrx:kernel:contract1:Quote", 1595 timeDistribution, 1596 SystemAttributes.MODIFIED_AT, 1597 CLOSED_THRESHOLD_QUOTE 1598 ); 1599 counts[3] = this.calculateTimeDistributionOpenContracts( 1600 header, 1601 assignedContractReference, 1602 "org:opencrx:kernel:contract1:Opportunity", 1603 timeDistribution, 1604 SystemAttributes.MODIFIED_AT, 1605 CLOSED_THRESHOLD_OPPORTUNITY 1606 ); 1607 counts[4] = this.calculateTimeDistributionOpenContracts( 1608 header, 1609 assignedContractReference, 1610 "org:opencrx:kernel:contract1:Lead", 1611 timeDistribution, 1612 SystemAttributes.MODIFIED_AT, 1613 CLOSED_THRESHOLD_LEAD 1614 ); 1615 1616 int maxValue = 0; 1617 for(int i = 0; i < counts.length; i++) { 1618 pw.println("CHART[0].VAL[" + i + "]:" + counts[i]); 1619 pw.println("CHART[0].BORDER[" + i + "]:#000066"); 1620 pw.println("CHART[0].FILL[" + i + "]:#F6D66D"); 1621 maxValue = Math.max(maxValue, counts[i]); 1622 } 1623 1624 pw.println("CHART[0].MINVALUE:0"); 1625 pw.println("CHART[0].MAXVALUE:" + maxValue); 1626 1627 pw.println("END:VND.OPENDMDX-CHART"); 1628 1629 try { 1630 pw.flush(); 1631 os.close(); 1632 } catch(Exception e) {} 1633 charts[0].values("chart").add( 1634 os.toByteArray() 1635 ); 1636 charts[0].values("chartMimeType").add("application/vnd.openmdx-chart"); 1637 charts[0].values("chartName").add( 1638 this.plugin.toFilename(chartTitle + ".txt") 1639 ); 1640 1641 1644 chartTitle = (fullName.length() == 0 ? "" : fullName + ": ") + "Assigned Open Contracts Age Distribution (" + createdAt + ")"; 1645 1646 charts[1] = new DataproviderObject( 1647 chartReference.getChild("1") 1648 ); 1649 charts[1].values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:home1:Chart"); 1650 charts[1].values("description").add(chartTitle); 1651 os = new ByteArrayOutputStream (); 1652 pw = new PrintWriter (os); 1653 1654 pw.println("BEGIN:VND.OPENDMDX-CHART"); 1655 pw.println("VERSION:1.0"); 1656 pw.println("COUNT:1"); 1657 1658 pw.println("CHART[0].TYPE:VERTBAR"); 1659 pw.println("CHART[0].LABEL:" + chartTitle); 1660 pw.println("CHART[0].SCALEXTITLE:#Days"); 1661 pw.println("CHART[0].SCALEYTITLE:#Contracts"); 1662 pw.println("CHART[0].COUNT:14"); 1663 1664 pw.println("CHART[0].LABEL[0]:new"); 1665 pw.println("CHART[0].LABEL[1]:1"); 1666 pw.println("CHART[0].LABEL[2]:2"); 1667 pw.println("CHART[0].LABEL[3]:3"); 1668 pw.println("CHART[0].LABEL[4]:4"); 1669 pw.println("CHART[0].LABEL[5]:5"); 1670 pw.println("CHART[0].LABEL[6]:6"); 1671 pw.println("CHART[0].LABEL[7]:7"); 1672 pw.println("CHART[0].LABEL[8]:..14"); 1673 pw.println("CHART[0].LABEL[9]:..30"); 1674 pw.println("CHART[0].LABEL[10]:..90"); 1675 pw.println("CHART[0].LABEL[11]:..180"); 1676 pw.println("CHART[0].LABEL[12]:..360"); 1677 pw.println("CHART[0].LABEL[13]:>360 days"); 1678 1679 maxValue = 0; 1680 for(int i = 0; i < 14; i++) { 1683 pw.println("CHART[0].VAL[" + i + "]:" + timeDistribution[i+1]); 1684 pw.println("CHART[0].BORDER[" + i + "]:#000066"); 1685 pw.println("CHART[0].FILL[" + i + "]:#F6D66D"); 1686 maxValue = Math.max(maxValue, timeDistribution[i+1]); 1687 } 1688 1689 pw.println("CHART[0].MINVALUE:0"); 1690 pw.println("CHART[0].MAXVALUE:" + maxValue); 1691 1692 pw.println("END:VND.OPENDMDX-CHART"); 1693 1694 try { 1695 pw.flush(); 1696 os.close(); 1697 } catch(Exception e) {} 1698 charts[1].values("chart").add( 1699 os.toByteArray() 1700 ); 1701 charts[1].values("chartMimeType").add("application/vnd.openmdx-chart"); 1702 charts[1].values("chartName").add( 1703 this.plugin.toFilename(chartTitle + ".txt") 1704 ); 1705 1706 return charts; 1707 } 1708 1709 public void markAsClosed( 1711 Path contractIdentity, 1712 DataproviderObject params 1713 ) throws ServiceException { 1714 DataproviderObject contract = this.plugin.retrieveObjectForModification(contractIdentity); 1715 String contractType = (String )contract.values(SystemAttributes.OBJECT_CLASS).get(0); 1716 Number newContractState = null; 1717 if("org:opencrx:kernel:contract1:Lead".equals(contractType)) { 1718 newContractState = (Number )params.values("leadState").get(0); 1719 } 1720 else if("org:opencrx:kernel:contract1:Opportunity".equals(contractType)) { 1721 newContractState = (Number )params.values("opportunityState").get(0); 1722 } 1723 else if("org:opencrx:kernel:contract1:Quote".equals(contractType)) { 1724 newContractState = (Number )params.values("quoteState").get(0); 1725 } 1726 else if("org:opencrx:kernel:contract1:SalesOrder".equals(contractType)) { 1727 newContractState = (Number )params.values("salesOrderState").get(0); 1728 } 1729 else if("org:opencrx:kernel:contract1:Invoice".equals(contractType)) { 1730 newContractState = (Number )params.values("invoiceState").get(0); 1731 } 1732 else { 1733 throw new ServiceException( 1734 BasicException.Code.DEFAULT_DOMAIN, 1735 BasicException.Code.NOT_SUPPORTED, 1736 new BasicException.Parameter[]{ 1737 new BasicException.Parameter("contract type", contractType) 1738 }, 1739 "Unsupported contract type. Supported are [Lead|Opportunity|Quote|SalesOrder|Invoice]" 1740 ); 1741 } 1742 contract.clearValues("closedOn").add( 1743 org.openmdx.base.text.format.DateFormat.getInstance().format(new Date ()) 1744 ); 1745 contract.clearValues("contractState").add( 1746 newContractState 1747 ); 1748 } 1749 1750 public boolean allowPositionRemoval( 1752 Path contractIdentity, 1753 DataproviderObject_1_0 productRole, 1754 Path parentPositionIdentity 1755 ) throws ServiceException { 1756 List positions = this.delegation.addFindRequest( 1757 contractIdentity.getChild("position"), 1758 parentPositionIdentity == null 1759 ? null 1760 : new FilterProperty[]{ 1761 new FilterProperty( 1762 Quantors.THERE_EXISTS, 1763 "parentPosition", 1764 FilterOperators.IS_IN, 1765 new Path[]{parentPositionIdentity} 1766 ) 1767 }, 1768 AttributeSelectors.ALL_ATTRIBUTES, 1769 0, 1770 Integer.MAX_VALUE, 1771 Directions.ASCENDING 1772 ); 1773 int nPositions = 0; 1774 for( 1775 Iterator i = positions.iterator(); 1776 i.hasNext(); 1777 ) { 1778 DataproviderObject_1_0 pos = (DataproviderObject_1_0)i.next(); 1779 if(productRole.path().equals(pos.values("basedOn").get(0))) { 1780 nPositions++; 1781 } 1782 } 1783 return nPositions > ((Number )productRole.values("minPositions").get(0)).intValue(); 1784 } 1785 1786 public boolean allowPositionCreation( 1788 Path contractIdentity, 1789 DataproviderObject_1_0 productRole, 1790 Path parentPositionIdentity 1791 ) throws ServiceException { 1792 List positions = this.delegation.addFindRequest( 1793 contractIdentity.getChild("position"), 1794 parentPositionIdentity == null 1795 ? null 1796 : new FilterProperty[]{ 1797 new FilterProperty( 1798 Quantors.THERE_EXISTS, 1799 "parentPosition", 1800 FilterOperators.IS_IN, 1801 new Path[]{parentPositionIdentity} 1802 ) 1803 }, 1804 AttributeSelectors.ALL_ATTRIBUTES, 1805 0, 1806 Integer.MAX_VALUE, 1807 Directions.ASCENDING 1808 ); 1809 int nPositions = 0; 1810 for( 1811 Iterator i = positions.iterator(); 1812 i.hasNext(); 1813 ) { 1814 DataproviderObject_1_0 pos = (DataproviderObject_1_0)i.next(); 1815 if(productRole.path().equals(pos.values("basedOn").get(0))) { 1816 nPositions++; 1817 } 1818 } 1819 return nPositions < ((Number )productRole.values("maxPositions").get(0)).intValue(); 1820 } 1821 1822 public void removeContractPosition( 1824 ServiceHeader header, 1825 DataproviderObject_1_0 position, 1826 boolean checkForMinPositions 1827 ) throws ServiceException { 1828 Path contractIdentity = position.path().getPrefix(position.path().size() - 2); 1829 Path productRoleIdentity = (Path)position.values("basedOn").get(0); 1830 if(productRoleIdentity != null) { 1831 DataproviderObject_1_0 productRole = this.plugin.retrieveObjectFromDelegation(productRoleIdentity); 1832 Path parentPositionIdentity = (Path)position.values("parentPosition").get(0); 1833 if(checkForMinPositions && !this.allowPositionRemoval(contractIdentity, productRole, parentPositionIdentity)) { 1834 throw new ServiceException( 1835 OpenCrxException.DOMAIN, 1836 OpenCrxException.CONTRACT_MIN_POSITIONS_REACHED, 1837 new BasicException.Parameter[]{ 1838 new BasicException.Parameter("param0", productRole.values("minPositions").get(0)), 1839 new BasicException.Parameter("param1", position.values("name").get(0)) 1840 }, 1841 "Removal not allowed. Min positions reached." 1842 ); 1843 } 1844 List positions = this.delegation.addFindRequest( 1846 contractIdentity.getChild("position"), 1847 new FilterProperty[]{ 1848 new FilterProperty( 1849 Quantors.THERE_EXISTS, 1850 "parentPosition", 1851 FilterOperators.IS_IN, 1852 new Path[]{position.path()} 1853 ) 1854 }, 1855 AttributeSelectors.ALL_ATTRIBUTES, 1856 0, 1857 Integer.MAX_VALUE, 1858 Directions.ASCENDING 1859 ); 1860 for( 1861 Iterator i = positions.iterator(); 1862 i.hasNext(); 1863 ) { 1864 DataproviderObject_1_0 childPosition = (DataproviderObject_1_0)i.next(); 1865 this.removeContractPosition( 1866 header, 1867 childPosition, 1868 false 1869 ); 1870 } 1871 } 1872 this.plugin.removeObject(position.path()); 1873 } 1874 1875 1879 private Set createDepotReferences( 1880 ServiceHeader header, 1881 Path depotHolderIdentity, 1882 Path positionIdentity, 1883 Set excludeDepotUsage 1884 ) throws ServiceException { 1885 Set depotUsages = new HashSet (); 1886 List depotReferences = this.delegation.addFindRequest( 1887 depotHolderIdentity.getChild("depotReference"), 1888 null, 1889 AttributeSelectors.ALL_ATTRIBUTES, 1890 0, 1891 Integer.MAX_VALUE, 1892 Directions.ASCENDING 1893 ); 1894 for( 1895 Iterator i = depotReferences.iterator(); 1896 i.hasNext(); 1897 ) { 1898 DataproviderObject_1_0 depotReference = (DataproviderObject_1_0)i.next(); 1899 Integer depotUsage = new Integer (((Number )depotReference.values("depotUsage").get(0)).intValue()); 1900 if(!excludeDepotUsage.contains(depotUsage)) { 1901 this.plugin.cloneable.cloneAndUpdateReferences( 1902 header, 1903 depotReference, 1904 positionIdentity.getChild("depotReference"), 1905 null, 1906 "", 1907 true 1908 ); 1909 } 1910 depotUsages.add(depotUsage); 1911 } 1912 return depotUsages; 1913 } 1914 1915 public DataproviderObject createProductOfferingPosition( 1917 ServiceHeader header, 1918 Path contractIdentity, 1919 Path productOfferingIdentity, 1920 BigDecimal quantity 1921 ) throws ServiceException { 1922 DataproviderObject_1_0 contract = this.plugin.retrieveObjectFromLocal( 1923 header, 1924 contractIdentity 1925 ); 1926 if(productOfferingIdentity == null) { 1927 throw new ServiceException( 1928 OpenCrxException.DOMAIN, 1929 OpenCrxException.CONTRACT_MISSING_PRODUCT_OFFERING, 1930 null, 1931 "missing product offering" 1932 ); 1933 } 1934 DataproviderObject_1_0 productOffering = this.plugin.retrieveObjectFromLocal( 1935 header, 1936 productOfferingIdentity 1937 ); 1938 if(!this.allowPositionCreation(contractIdentity, productOffering, null)) { 1939 throw new ServiceException( 1940 OpenCrxException.DOMAIN, 1941 OpenCrxException.CONTRACT_MAX_POSITIONS_REACHED, 1942 new BasicException.Parameter[]{ 1943 new BasicException.Parameter("param0", productOffering.values("maxPositions").get(0)) 1944 }, 1945 "Creation not allowed. Max positions reached." 1946 ); 1947 } 1948 1949 String contractType = (String )contract.values(SystemAttributes.OBJECT_CLASS).get(0); 1950 DataproviderObject position = new DataproviderObject( 1951 contractIdentity.getDescendant(new String []{"position", this.plugin.getUidAsString()}) 1952 ); 1953 if("org:opencrx:kernel:contract1:Opportunity".equals(contractType)) { 1954 position.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:OpportunityProductOfferingPosition"); 1955 } 1956 else if("org:opencrx:kernel:contract1:Quote".equals(contractType)) { 1957 position.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:QuoteProductOfferingPosition"); 1958 } 1959 else if("org:opencrx:kernel:contract1:SalesOrder".equals(contractType)) { 1960 position.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:SalesOrderProductOfferingPosition"); 1961 } 1962 else if("org:opencrx:kernel:contract1:Invoice".equals(contractType)) { 1963 position.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:InvoiceProductOfferingPosition"); 1964 } 1965 else { 1966 throw new ServiceException( 1967 BasicException.Code.DEFAULT_DOMAIN, 1968 BasicException.Code.NOT_SUPPORTED, 1969 new BasicException.Parameter[]{ 1970 new BasicException.Parameter("contract type", contractType) 1971 }, 1972 "Unsupported contract type. Supported are [Lead|Opportunity|Quote|SalesOrder|Invoice]" 1973 ); 1974 } 1975 position.values("basedOn").add(productOfferingIdentity); 1976 position.values("lineItemNumber").add( 1977 new Integer ( 1978 100000 * (this.getMaxLineItemNumber(contract, null) / 100000 + 1) 1979 ) 1980 ); 1981 position.values("name").addAll(productOffering.values("name")); 1982 position.values("description").addAll(productOffering.values("description")); 1983 position.values("contractPositionState").add( 1984 new Integer (0) 1985 ); 1986 quantity = (quantity == null) || quantity.compareTo(new BigDecimal (0)) == 0 1987 ? productOffering.values("defaultQuantity").size() == 0 1988 ? new BigDecimal (1) 1989 : (BigDecimal )productOffering.values("defaultQuantity").get(0) 1990 : quantity; 1991 position.values("quantity").add(quantity); 1992 position.values("minQuantity").addAll(productOffering.values("minQuantity")); 1993 position.values("maxQuantity").addAll(productOffering.values("maxQuantity")); 1994 position.values("offsetQuantity").addAll(productOffering.values("offsetQuantity")); 1995 position.values("minMaxQuantityHandling").addAll(productOffering.values("minMaxQuantityHandling")); 1996 position.values("discountIsPercentage").addAll(productOffering.values("discountIsPercentage")); 1997 position.values("discount").addAll(productOffering.values("discount")); 1998 this.updateContractPositionPrice( 1999 contract, 2000 position, 2001 null, 2002 productOffering, 2003 true 2004 ); 2005 if( 2007 (productOffering.values("overridePrice").size() == 0) || !((Boolean )productOffering.values("overridePrice").get(0)).booleanValue() 2008 ) { 2009 position.clearValues("pricePerUnit").add(new BigDecimal (0.0)); 2010 } 2011 this.delegation.addCreateRequest( 2012 position 2013 ); 2014 2015 this.createDepotReferences( 2017 header, 2018 productOffering.path(), 2019 position.path(), 2020 new HashSet () 2021 ); 2022 2023 List productBundles = this.delegation.addFindRequest( 2025 productOffering.path().getChild("productBundle"), 2026 null, 2027 AttributeSelectors.ALL_ATTRIBUTES, 2028 new AttributeSpecifier[]{ 2029 new AttributeSpecifier("itemNumber", 0, Orders.ASCENDING) 2030 }, 2031 0, 2032 Integer.MAX_VALUE, 2033 Directions.ASCENDING 2034 ); 2035 for( 2036 Iterator i = productBundles.iterator(); 2037 i.hasNext(); 2038 ) { 2039 DataproviderObject_1_0 productBundle = (DataproviderObject_1_0)i.next(); 2040 int defaultPositions = productBundle.values("defaultPositions").size() == 0 2041 ? 0 2042 : ((Number )productBundle.values("defaultPositions").get(0)).intValue(); 2043 for( 2044 int j = 0; 2045 j < defaultPositions; 2046 j++ 2047 ) { 2048 BigDecimal positionQuantity = (BigDecimal )position.values("quantity").get(0); 2049 this.createProductBundlePosition( 2050 header, 2051 position.path(), 2052 contractIdentity, 2053 productBundle.path(), 2054 positionQuantity.multiply((BigDecimal )productBundle.values("defaultQuantity").get(0)) 2055 ); 2056 } 2057 } 2058 return position; 2059 } 2060 2061 public DataproviderObject createProductBundlePosition( 2063 ServiceHeader header, 2064 Path parentPositionIdentity, 2065 Path contractIdentity, 2066 Path productBundleIdentity, 2067 BigDecimal quantity 2068 ) throws ServiceException { 2069 DataproviderObject_1_0 contract = this.plugin.retrieveObjectFromLocal( 2070 header, 2071 contractIdentity 2072 ); 2073 DataproviderObject_1_0 parentPosition = this.plugin.retrieveObjectFromLocal( 2074 header, 2075 parentPositionIdentity 2076 ); 2077 DataproviderObject_1_0 productBundle = this.plugin.retrieveObjectFromLocal( 2078 header, 2079 productBundleIdentity 2080 ); 2081 if(!this.allowPositionCreation(contractIdentity, productBundle, parentPositionIdentity)) { 2082 throw new ServiceException( 2083 OpenCrxException.DOMAIN, 2084 OpenCrxException.CONTRACT_MAX_POSITIONS_REACHED, 2085 new BasicException.Parameter[]{ 2086 new BasicException.Parameter("param0", productBundle.values("maxPositions").get(0)) 2087 }, 2088 "Creation not allowed. Max positions reached." 2089 ); 2090 } 2091 DataproviderObject_1_0 productBundleType = this.plugin.retrieveObjectFromLocal( 2092 header, 2093 (Path)productBundle.values("bundleType").get(0) 2094 ); 2095 DataproviderObject_1_0 productOffering = this.plugin.retrieveObjectFromLocal( 2096 header, 2097 productBundleIdentity.getPrefix(productBundleIdentity.size() - 2) 2098 ); 2099 String contractType = (String )contract.values(SystemAttributes.OBJECT_CLASS).get(0); 2100 DataproviderObject position = new DataproviderObject( 2101 contractIdentity.getDescendant(new String []{"position", this.plugin.getUidAsString()}) 2102 ); 2103 if("org:opencrx:kernel:contract1:Opportunity".equals(contractType)) { 2104 position.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:OpportunityProductBundlePosition"); 2105 } 2106 else if("org:opencrx:kernel:contract1:Quote".equals(contractType)) { 2107 position.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:QuoteProductBundlePosition"); 2108 } 2109 else if("org:opencrx:kernel:contract1:SalesOrder".equals(contractType)) { 2110 position.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:SalesOrderProductBundlePosition"); 2111 } 2112 else if("org:opencrx:kernel:contract1:Invoice".equals(contractType)) { 2113 position.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:InvoiceProductBundlePosition"); 2114 } 2115 else { 2116 throw new ServiceException( 2117 BasicException.Code.DEFAULT_DOMAIN, 2118 BasicException.Code.NOT_SUPPORTED, 2119 new BasicException.Parameter[]{ 2120 new BasicException.Parameter("contract type", contractType) 2121 }, 2122 "Unsupported contract type. Supported are [Lead|Opportunity|Quote|SalesOrder|Invoice]" 2123 ); 2124 } 2125 position.values("basedOn").add(productBundleIdentity); 2126 position.values("parentPosition").add(parentPositionIdentity); 2127 position.values("lineItemNumber").add( 2128 new Integer ( 2129 java.lang.Math.max( 2130 this.getMaxLineItemNumber(contract, parentPositionIdentity) + 100, 2131 ((Number )parentPosition.values("lineItemNumber").get(0)).intValue() + 100 2132 ) 2133 ) 2134 ); 2135 position.values("name").addAll(productBundle.values("name")); 2136 position.values("description").addAll(productBundle.values("description")); 2137 position.values("contractPositionState").add( 2138 new Integer (0) 2139 ); 2140 position.values("quantity").add( 2141 quantity == null 2142 ? productBundle.values("defaultQuantity").get(0) 2143 : quantity 2144 ); 2145 position.values("minQuantity").addAll(productBundle.values("minQuantity")); 2146 position.values("maxQuantity").addAll(productBundle.values("maxQuantity")); 2147 position.values("offsetQuantity").addAll(productBundle.values("offsetQuantity")); 2148 position.values("minMaxQuantityHandling").addAll(productBundle.values("minMaxQuantityHandling")); 2149 position.values("discountIsPercentage").addAll(productBundle.values("discountIsPercentage")); 2150 position.values("discount").addAll(productBundle.values("discount")); 2151 if( 2153 ((productBundle.values("overridePrice").size() == 0) || !((Boolean )productBundle.values("overridePrice").get(0)).booleanValue()) 2154 ) { 2155 boolean priceSet = this.updateContractPositionPrice( 2156 contract, 2157 position, 2158 null, 2159 productBundleType, 2160 true 2161 ); 2162 if( 2164 ((productBundleType.values("overridePrice").size() == 0) || !((Boolean )productBundleType.values("overridePrice").get(0)).booleanValue()) 2165 ) { 2166 position.clearValues("pricePerUnit").add(new BigDecimal (0.0)); 2167 } 2168 if(!priceSet) { 2170 this.updateContractPositionPrice( 2171 contract, 2172 position, 2173 null, 2174 productBundle, 2175 true 2176 ); 2177 position.clearValues("pricePerUnit").add(new BigDecimal (0.0)); 2179 } 2180 } 2181 else { 2183 this.updateContractPositionPrice( 2184 contract, 2185 position, 2186 null, 2187 productBundle, 2188 true 2189 ); 2190 } 2191 if( 2193 ((productOffering.values("overridePrice").size() > 0) && ((Boolean )productOffering.values("overridePrice").get(0)).booleanValue()) 2194 ) { 2195 position.clearValues("pricePerUnit").add(new BigDecimal (0.0)); 2196 } 2197 this.delegation.addCreateRequest( 2198 position 2199 ); 2200 2201 this.createDepotReferences( 2203 header, 2204 productBundle.path(), 2205 position.path(), 2206 new HashSet () 2207 ); 2208 2209 List bundledProducts = this.delegation.addFindRequest( 2211 productBundleType.path().getChild("bundledProduct"), 2212 null, 2213 AttributeSelectors.ALL_ATTRIBUTES, 2214 new AttributeSpecifier[]{ 2215 new AttributeSpecifier("itemNumber", 0, Orders.ASCENDING) 2216 }, 2217 0, 2218 Integer.MAX_VALUE, 2219 Directions.ASCENDING 2220 ); 2221 for( 2222 Iterator i = bundledProducts.iterator(); 2223 i.hasNext(); 2224 ) { 2225 DataproviderObject_1_0 bundledProduct = (DataproviderObject_1_0)i.next(); 2226 int defaultPositions = bundledProduct.values("defaultPositions").size() == 0 2227 ? 0 2228 : ((Number )bundledProduct.values("defaultPositions").get(0)).intValue(); 2229 for( 2230 int j = 0; 2231 j < defaultPositions; 2232 j++ 2233 ) { 2234 BigDecimal positionQuantity = (BigDecimal )position.values("quantity").get(0); 2235 this.createBundledProductPosition( 2236 header, 2237 position.path(), 2238 contractIdentity, 2239 bundledProduct.path(), 2240 positionQuantity.multiply((BigDecimal )bundledProduct.values("defaultQuantity").get(0)) 2241 ); 2242 } 2243 } 2244 return position; 2245 } 2246 2247 public DataproviderObject createBundledProductPosition( 2249 ServiceHeader header, 2250 Path parentPositionIdentity, 2251 Path contractIdentity, 2252 Path bundledProductIdentity, 2253 BigDecimal quantity 2254 ) throws ServiceException { 2255 DataproviderObject_1_0 contract = this.plugin.retrieveObjectFromLocal( 2256 header, 2257 contractIdentity 2258 ); 2259 DataproviderObject_1_0 parentPosition = this.plugin.retrieveObjectFromLocal( 2260 header, 2261 parentPositionIdentity 2262 ); 2263 DataproviderObject_1_0 productBundle = this.plugin.retrieveObjectFromLocal( 2264 header, 2265 (Path)parentPosition.values("basedOn").get(0) 2266 ); 2267 DataproviderObject_1_0 productBundleType = this.plugin.retrieveObjectFromLocal( 2268 header, 2269 (Path)productBundle.values("bundleType").get(0) 2270 ); 2271 DataproviderObject_1_0 bundledProduct = this.plugin.retrieveObjectFromLocal( 2272 header, 2273 bundledProductIdentity 2274 ); 2275 if(!this.allowPositionCreation(contractIdentity, bundledProduct, parentPositionIdentity)) { 2276 throw new ServiceException( 2277 OpenCrxException.DOMAIN, 2278 OpenCrxException.CONTRACT_MAX_POSITIONS_REACHED, 2279 new BasicException.Parameter[]{ 2280 new BasicException.Parameter("param0", bundledProduct.values("maxPositions").get(0)) 2281 }, 2282 "Creation not allowed. Max positions reached." 2283 ); 2284 } 2285 DataproviderObject_1_0 product = this.plugin.retrieveObjectFromLocal( 2286 header, 2287 (Path)bundledProduct.values("product").get(0) 2288 ); 2289 DataproviderObject_1_0 productOffering = this.plugin.retrieveObjectFromLocal( 2290 header, 2291 productBundle.path().getPrefix(productBundle.path().size() - 2) 2292 ); 2293 String contractType = (String )contract.values(SystemAttributes.OBJECT_CLASS).get(0); 2294 2295 DataproviderObject position = new DataproviderObject( 2297 contractIdentity.getDescendant(new String []{"position", this.plugin.getUidAsString()}) 2298 ); 2299 if("org:opencrx:kernel:contract1:Opportunity".equals(contractType)) { 2300 position.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:OpportunityBundledProductPosition"); 2301 } 2302 else if("org:opencrx:kernel:contract1:Quote".equals(contractType)) { 2303 position.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:QuoteBundledProductPosition"); 2304 } 2305 else if("org:opencrx:kernel:contract1:SalesOrder".equals(contractType)) { 2306 position.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:SalesOrderBundledProductPosition"); 2307 } 2308 else if("org:opencrx:kernel:contract1:Invoice".equals(contractType)) { 2309 position.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:contract1:InvoiceBundledProductPosition"); 2310 } 2311 else { 2312 throw new ServiceException( 2313 BasicException.Code.DEFAULT_DOMAIN, 2314 BasicException.Code.NOT_SUPPORTED, 2315 new BasicException.Parameter[]{ 2316 new BasicException.Parameter("contract type", contractType) 2317 }, 2318 "Unsupported contract type. Supported are [Lead|Opportunity|Quote|SalesOrder|Invoice]" 2319 ); 2320 } 2321 position.values("basedOn").add(bundledProductIdentity); 2322 position.values("parentPosition").add(parentPositionIdentity); 2323 position.values("lineItemNumber").add( 2324 new Integer ( 2325 java.lang.Math.max( 2326 this.getMaxLineItemNumber(contract, parentPositionIdentity) + 1, 2327 ((Number )parentPosition.values("lineItemNumber").get(0)).intValue() + 1 2328 ) 2329 ) 2330 ); 2331 position.values("name").addAll(bundledProduct.values("name")); 2332 position.values("description").addAll(bundledProduct.values("description")); 2333 position.values("contractPositionState").add( 2334 new Integer (0) 2335 ); 2336 position.values("quantity").add( 2337 quantity == null 2338 ? bundledProduct.values("defaultQuantity").get(0) 2339 : quantity 2340 ); 2341 position.values("minQuantity").addAll(bundledProduct.values("minQuantity")); 2342 position.values("maxQuantity").addAll(bundledProduct.values("maxQuantity")); 2343 position.values("offsetQuantity").addAll(bundledProduct.values("offsetQuantity")); 2344 position.values("minMaxQuantityHandling").addAll(bundledProduct.values("minMaxQuantityHandling")); 2345 position.values("discountIsPercentage").addAll(bundledProduct.values("discountIsPercentage")); 2346 position.values("discount").addAll(bundledProduct.values("discount")); 2347 position.values("product").addAll(bundledProduct.values("product")); 2348 boolean priceSet = this.updateContractPositionPrice( 2349 contract, 2350 position, 2351 null, 2352 bundledProduct, 2353 true 2354 ); 2355 if( 2357 ((bundledProduct.values("overridePrice").size() == 0) || !((Boolean )bundledProduct.values("overridePrice").get(0)).booleanValue()) 2358 ) { 2359 position.clearValues("pricePerUnit").add(new BigDecimal (0.0)); 2360 } 2361 if(!priceSet) { 2362 this.updateContractPositionPrice( 2363 contract, 2364 position, 2365 null, 2366 product, 2367 true 2368 ); 2369 } 2370 if( 2372 ((productBundle.values("overridePrice").size() > 0) && ((Boolean )productBundle.values("overridePrice").get(0)).booleanValue()) || 2373 ((productBundleType.values("overridePrice").size() > 0) && ((Boolean )productBundleType.values("overridePrice").get(0)).booleanValue()) || 2374 ((productOffering.values("overridePrice").size() > 0) && ((Boolean )productOffering.values("overridePrice").get(0)).booleanValue()) 2375 ) { 2376 position.clearValues("pricePerUnit").add(new BigDecimal (0.0)); 2377 } 2378 this.delegation.addCreateRequest( 2379 position 2380 ); 2381 Set depotUsages = this.createDepotReferences( 2384 header, 2385 bundledProduct.path(), 2386 position.path(), 2387 new HashSet () 2388 ); 2389 this.createDepotReferences( 2392 header, 2393 product.path(), 2394 position.path(), 2395 depotUsages 2396 ); 2397 this.plugin.products.cloneProductConfigurationSet( 2399 header, 2400 bundledProductIdentity, 2401 position.path(), 2402 true, 2403 true 2404 ); 2405 return position; 2406 } 2407 2408 public DataproviderObject createSelectableProductBundleFromContractPosition( 2410 Path offeringPositionIdentity, 2411 int itemNumber, 2412 DataproviderObject_1_0 contractPosition 2413 ) throws ServiceException { 2414 DataproviderObject_1_0 productBundle = this.plugin.retrieveObjectFromDelegation( 2415 (Path)contractPosition.values("basedOn").get(0) 2416 ); 2417 DataproviderObject selectableBundle = new DataproviderObject( 2419 offeringPositionIdentity.getDescendant(new String []{"selectableItem", MODIFY_PRODUCT_BUNDLE_POSITION + ":position=" + contractPosition.path().getBase()}) 2420 ); 2421 selectableBundle.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:product1:SelectableProductBundle"); 2422 selectableBundle.values("itemNumber").add(new Integer (itemNumber)); 2423 selectableBundle.values("name").addAll(contractPosition.values("name")); 2424 selectableBundle.values("description").addAll(contractPosition.values("description")); 2425 selectableBundle.values("selector").add(Boolean.TRUE); 2426 selectableBundle.values("quantity").addAll(contractPosition.values("quantity")); 2427 selectableBundle.values("minQuantity").addAll(productBundle.values("minQuantity")); 2428 selectableBundle.values("maxQuantity").addAll(productBundle.values("maxQuantity")); 2429 selectableBundle.values("defaultQuantity").addAll(productBundle.values("defaultQuantity")); 2430 selectableBundle.values("basedOn").add(productBundle.path()); 2431 selectableBundle.values("owningUser").addAll(contractPosition.values("owningUser")); 2432 selectableBundle.values("owningGroup").addAll(contractPosition.values("owningGroup")); 2433 selectableBundle.values(SystemAttributes.OBJECT_IDENTITY).add(selectableBundle.path().toXri()); 2434 selectableBundle.values(SystemAttributes.CREATED_AT).addAll(contractPosition.values(SystemAttributes.CREATED_AT)); 2435 selectableBundle.values(SystemAttributes.MODIFIED_AT).addAll(contractPosition.values(SystemAttributes.MODIFIED_AT)); 2436 selectableBundle.values(SystemAttributes.CREATED_BY).addAll(contractPosition.values(SystemAttributes.CREATED_BY)); 2437 selectableBundle.values(SystemAttributes.MODIFIED_BY).addAll(contractPosition.values(SystemAttributes.MODIFIED_BY)); 2438 return selectableBundle; 2439 } 2440 2441 public DataproviderObject createSelectableProductBundleFromProductBundle( 2443 Path offeringPositionIdentity, 2444 int itemNumber, 2445 DataproviderObject_1_0 productBundle 2446 ) throws ServiceException { 2447 DataproviderObject selectableBundle = new DataproviderObject( 2449 offeringPositionIdentity.getDescendant(new String []{"selectableItem", NEW_PRODUCT_BUNDLE_POSITION + ":parent=" + offeringPositionIdentity.getBase() + ":productBundleId=" + productBundle.path().getBase()}) 2450 ); 2451 selectableBundle.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:product1:SelectableProductBundle"); 2452 selectableBundle.values("itemNumber").add(new Integer (itemNumber)); 2453 selectableBundle.values("name").addAll(productBundle.values("name")); 2454 selectableBundle.values("description").addAll(productBundle.values("description")); 2455 selectableBundle.values("selector").add(Boolean.FALSE); 2456 selectableBundle.values("quantity").addAll(productBundle.values("defaultQuantity")); 2457 selectableBundle.values("minQuantity").addAll(productBundle.values("minQuantity")); 2458 selectableBundle.values("maxQuantity").addAll(productBundle.values("maxQuantity")); 2459 selectableBundle.values("defaultQuantity").addAll(productBundle.values("defaultQuantity")); 2460 selectableBundle.values("basedOn").add(productBundle.path()); 2461 selectableBundle.values("owningUser").addAll(productBundle.values("owningUser")); 2462 selectableBundle.values("owningGroup").addAll(productBundle.values("owningGroup")); 2463 selectableBundle.values(SystemAttributes.OBJECT_IDENTITY).add(selectableBundle.path().toXri()); 2464 selectableBundle.values(SystemAttributes.CREATED_AT).addAll(productBundle.values(SystemAttributes.CREATED_AT)); 2465 selectableBundle.values(SystemAttributes.MODIFIED_AT).addAll(productBundle.values(SystemAttributes.MODIFIED_AT)); 2466 selectableBundle.values(SystemAttributes.CREATED_BY).addAll(productBundle.values(SystemAttributes.CREATED_BY)); 2467 selectableBundle.values(SystemAttributes.MODIFIED_BY).addAll(productBundle.values(SystemAttributes.MODIFIED_BY)); 2468 return selectableBundle; 2469 } 2470 2471 public DataproviderObject createSelectableBundledProductFromContractPosition( 2473 Path offeringPositionIdentity, 2474 int itemNumber, 2475 DataproviderObject_1_0 contractPosition 2476 ) throws ServiceException { 2477 DataproviderObject_1_0 bundledProduct = this.plugin.retrieveObjectFromDelegation( 2478 (Path)contractPosition.values("basedOn").get(0) 2479 ); 2480 DataproviderObject selectableBundledProduct = new DataproviderObject( 2482 offeringPositionIdentity.getDescendant(new String []{"selectableItem", MODIFY_BUNDLED_PRODUCT_POSITION + ":position=" + contractPosition.path().getBase()}) 2483 ); 2484 selectableBundledProduct.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:product1:SelectableBundledProduct"); 2485 selectableBundledProduct.values("itemNumber").add(new Integer (itemNumber)); 2486 selectableBundledProduct.values("name").addAll(contractPosition.values("name")); 2487 selectableBundledProduct.values("description").addAll(contractPosition.values("description")); 2488 selectableBundledProduct.values("selector").add(Boolean.TRUE); 2489 selectableBundledProduct.values("quantity").addAll(contractPosition.values("quantity")); 2490 selectableBundledProduct.values("minQuantity").addAll(bundledProduct.values("minQuantity")); 2491 selectableBundledProduct.values("maxQuantity").addAll(bundledProduct.values("maxQuantity")); 2492 selectableBundledProduct.values("defaultQuantity").addAll(bundledProduct.values("defaultQuantity")); 2493 selectableBundledProduct.values("basedOn").add(bundledProduct.path()); 2494 selectableBundledProduct.values("owningUser").addAll(contractPosition.values("owningUser")); 2495 selectableBundledProduct.values("owningGroup").addAll(contractPosition.values("owningGroup")); 2496 selectableBundledProduct.values(SystemAttributes.OBJECT_IDENTITY).add(selectableBundledProduct.path().toXri()); 2497 selectableBundledProduct.values(SystemAttributes.CREATED_AT).addAll(bundledProduct.values(SystemAttributes.CREATED_AT)); 2498 selectableBundledProduct.values(SystemAttributes.MODIFIED_AT).addAll(bundledProduct.values(SystemAttributes.MODIFIED_AT)); 2499 selectableBundledProduct.values(SystemAttributes.CREATED_BY).addAll(bundledProduct.values(SystemAttributes.CREATED_BY)); 2500 selectableBundledProduct.values(SystemAttributes.MODIFIED_BY).addAll(bundledProduct.values(SystemAttributes.MODIFIED_BY)); 2501 return selectableBundledProduct; 2502 } 2503 2504 public DataproviderObject createSelectableBundledProductFromBundledProduct( 2506 Path offeringPositionIdentity, 2507 Path productBundlePositionIdentity, 2508 int itemNumber, 2509 DataproviderObject_1_0 bundledProduct 2510 ) throws ServiceException { 2511 DataproviderObject selectableBundledProduct = new DataproviderObject( 2512 offeringPositionIdentity.getDescendant(new String []{"selectableItem", NEW_BUNDLED_PRODUCT_POSITION + ":parent=" + productBundlePositionIdentity.getBase() + ":bundledProductId=" + bundledProduct.path().getBase()}) 2513 ); 2514 selectableBundledProduct.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:product1:SelectableBundledProduct"); 2515 selectableBundledProduct.values("itemNumber").add(new Integer (itemNumber)); 2516 selectableBundledProduct.values("name").addAll(bundledProduct.values("name")); 2517 selectableBundledProduct.values("description").addAll(bundledProduct.values("description")); 2518 selectableBundledProduct.values("selector").add(Boolean.FALSE); 2519 selectableBundledProduct.values("quantity").addAll(bundledProduct.values("defaultQuantity")); 2520 selectableBundledProduct.values("minQuantity").addAll(bundledProduct.values("minQuantity")); 2521 selectableBundledProduct.values("maxQuantity").addAll(bundledProduct.values("maxQuantity")); 2522 selectableBundledProduct.values("defaultQuantity").addAll(bundledProduct.values("defaultQuantity")); 2523 selectableBundledProduct.values("basedOn").add(bundledProduct.path()); 2524 selectableBundledProduct.values("owningUser").addAll(bundledProduct.values("owningUser")); 2525 selectableBundledProduct.values("owningGroup").addAll(bundledProduct.values("owningGroup")); 2526 selectableBundledProduct.values(SystemAttributes.OBJECT_IDENTITY).add(selectableBundledProduct.path().toXri()); 2527 selectableBundledProduct.values(SystemAttributes.CREATED_AT).addAll(bundledProduct.values(SystemAttributes.CREATED_AT)); 2528 selectableBundledProduct.values(SystemAttributes.MODIFIED_AT).addAll(bundledProduct.values(SystemAttributes.MODIFIED_AT)); 2529 selectableBundledProduct.values(SystemAttributes.CREATED_BY).addAll(bundledProduct.values(SystemAttributes.CREATED_BY)); 2530 selectableBundledProduct.values(SystemAttributes.MODIFIED_BY).addAll(bundledProduct.values(SystemAttributes.MODIFIED_BY)); 2531 return selectableBundledProduct; 2532 } 2533 2534 public DataproviderObject createSelectableProductConfigurationFromContractPosition( 2536 Path offeringPositionIdentity, 2537 Path contractPosition, 2538 int itemNumber, 2539 DataproviderObject_1_0 productConfiguration 2540 ) throws ServiceException { 2541 DataproviderObject selectableProductConfiguration = new DataproviderObject( 2542 offeringPositionIdentity.getDescendant(new String []{"selectableItem", MODIFY_CONFIGURATION + ":position=" + contractPosition.getBase() + ":configId=" + productConfiguration.path().getBase()}) 2543 ); 2544 selectableProductConfiguration.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:product1:SelectableProductConfiguration"); 2545 selectableProductConfiguration.values("itemNumber").add(new Integer (itemNumber)); 2546 selectableProductConfiguration.values("name").addAll(productConfiguration.values("name")); 2547 selectableProductConfiguration.values("description").addAll(productConfiguration.values("description")); 2548 selectableProductConfiguration.values("selector").add(Boolean.TRUE); 2549 selectableProductConfiguration.values("basedOn").add(productConfiguration.path()); 2550 selectableProductConfiguration.values("owningUser").addAll(productConfiguration.values("owningUser")); 2551 selectableProductConfiguration.values("owningGroup").addAll(productConfiguration.values("owningGroup")); 2552 selectableProductConfiguration.values(SystemAttributes.OBJECT_IDENTITY).add(selectableProductConfiguration.path().toXri()); 2553 selectableProductConfiguration.values(SystemAttributes.CREATED_AT).addAll(productConfiguration.values(SystemAttributes.CREATED_AT)); 2554 selectableProductConfiguration.values(SystemAttributes.MODIFIED_AT).addAll(productConfiguration.values(SystemAttributes.MODIFIED_AT)); 2555 selectableProductConfiguration.values(SystemAttributes.CREATED_BY).addAll(productConfiguration.values(SystemAttributes.CREATED_BY)); 2556 selectableProductConfiguration.values(SystemAttributes.MODIFIED_BY).addAll(productConfiguration.values(SystemAttributes.MODIFIED_BY)); 2557 return selectableProductConfiguration; 2558 } 2559 2560 public DataproviderObject createSelectableProductConfigurationFromBundledProduct( 2562 Path offeringPositionIdentity, 2563 Path bundledProductPositionIdentity, 2564 int itemNumber, 2565 DataproviderObject_1_0 productConfiguration 2566 ) throws ServiceException { 2567 DataproviderObject selectableProductConfiguration = new DataproviderObject( 2568 offeringPositionIdentity.getDescendant(new String []{"selectableItem", NEW_CONFIGURATION + ":parent=" + bundledProductPositionIdentity.getBase() + ":configId=" + productConfiguration.path().getBase()}) 2569 ); 2570 selectableProductConfiguration.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:product1:SelectableProductConfiguration"); 2571 selectableProductConfiguration.values("itemNumber").add(new Integer (itemNumber)); 2572 selectableProductConfiguration.values("name").addAll(productConfiguration.values("name")); 2573 selectableProductConfiguration.values("description").addAll(productConfiguration.values("description")); 2574 selectableProductConfiguration.values("selector").add(Boolean.FALSE); 2575 selectableProductConfiguration.values("basedOn").add(productConfiguration.path()); 2576 selectableProductConfiguration.values("owningUser").addAll(productConfiguration.values("owningUser")); 2577 selectableProductConfiguration.values("owningGroup").addAll(productConfiguration.values("owningGroup")); 2578 selectableProductConfiguration.values(SystemAttributes.OBJECT_IDENTITY).add(selectableProductConfiguration.path().toXri()); 2579 selectableProductConfiguration.values(SystemAttributes.CREATED_AT).addAll(productConfiguration.values(SystemAttributes.CREATED_AT)); 2580 selectableProductConfiguration.values(SystemAttributes.MODIFIED_AT).addAll(productConfiguration.values(SystemAttributes.MODIFIED_AT)); 2581 selectableProductConfiguration.values(SystemAttributes.CREATED_BY).addAll(productConfiguration.values(SystemAttributes.CREATED_BY)); 2582 selectableProductConfiguration.values(SystemAttributes.MODIFIED_BY).addAll(productConfiguration.values(SystemAttributes.MODIFIED_BY)); 2583 return selectableProductConfiguration; 2584 } 2585 2586 public void processSelectableItem( 2588 ServiceHeader header, 2589 DataproviderRequest request 2590 ) throws ServiceException { 2591 2592 String selectableItemId = request.path().getBase(); 2593 DataproviderObject newValue = request.object(); 2594 Boolean selector = request.object().getValues("selector") == null 2595 ? null 2596 : (Boolean )request.object().getValues("selector").get(0); 2597 String command = selectableItemId.substring(0, selectableItemId.indexOf(":")); 2598 2599 if(MODIFY_PRODUCT_BUNDLE_POSITION.equals(command)) { 2600 String positionId = selectableItemId.substring(selectableItemId.indexOf(":position=")+10); 2601 if(selector != null) { 2602 if(!selector.booleanValue()) { 2604 try { 2605 DataproviderObject_1_0 productBundlePosition = this.plugin.retrieveObjectFromLocal( 2606 header, 2607 request.path().getPrefix(request.path().size()-3).getChild(positionId) 2608 ); 2609 this.removeContractPosition( 2610 header, 2611 productBundlePosition, 2612 true 2613 ); 2614 } 2615 catch(ServiceException e) { 2616 if(e.getExceptionCode() != BasicException.Code.NOT_FOUND) { 2617 throw e; 2618 } 2619 } 2620 } 2621 } 2622 else { 2624 DataproviderObject_1_0 productBundlePosition = this.plugin.retrieveObjectFromLocal( 2625 header, 2626 request.path().getPrefix(request.path().size()-3).getChild(positionId) 2627 ); 2628 if( 2629 (newValue.containsAttributeName("name") && !newValue.values("name").get(0).equals(productBundlePosition.values("name").get(0))) || 2630 (newValue.containsAttributeName("description") && !newValue.values("description").get(0).equals(productBundlePosition.values("description").get(0))) || 2631 (newValue.containsAttributeName("quantity") && (((BigDecimal )newValue.values("quantity").get(0)).compareTo(productBundlePosition.values("quantity").get(0)) != 0)) 2632 ) { 2633 DataproviderObject modifiedProductBundlePosition = this.plugin.retrieveObjectForModification( 2634 request.path().getPrefix(request.path().size()-3).getChild(positionId) 2635 ); 2636 if(newValue.containsAttributeName("name")) { 2637 modifiedProductBundlePosition.clearValues("name").addAll( 2638 newValue.values("name") 2639 ); 2640 } 2641 if(newValue.containsAttributeName("description")) { 2642 modifiedProductBundlePosition.clearValues("description").addAll( 2643 newValue.values("description") 2644 ); 2645 } 2646 if(newValue.containsAttributeName("quantity")) { 2647 modifiedProductBundlePosition.clearValues("quantity").addAll( 2648 newValue.values("quantity") 2649 ); 2650 } 2651 } 2652 } 2653 } 2654 else if(NEW_PRODUCT_BUNDLE_POSITION.equals(command)) { 2655 if((selector != null) && selector.booleanValue()) { 2657 String parentId = selectableItemId.substring( 2658 selectableItemId.indexOf(":parent=")+8, 2659 selectableItemId.indexOf(":productBundleId=") 2660 ); 2661 DataproviderObject_1_0 offeringPosition = this.plugin.retrieveObjectFromLocal( 2662 header, 2663 request.path().getPrefix(request.path().size()-3).getChild(parentId) 2664 ); 2665 String productBundleId = selectableItemId.substring( 2666 selectableItemId.indexOf(":productBundleId=")+17 2667 ); 2668 this.createProductBundlePosition( 2669 header, 2670 offeringPosition.path(), 2671 offeringPosition.path().getPrefix(offeringPosition.path().size()-2), 2672 ((Path)offeringPosition.values("basedOn").get(0)).getDescendant(new String []{"productBundle", productBundleId}), 2673 (BigDecimal )newValue.values("quantity").get(0) 2674 ); 2675 } 2676 } 2677 else if(MODIFY_BUNDLED_PRODUCT_POSITION.equals(command)) { 2678 String positionId = selectableItemId.substring(selectableItemId.indexOf(":position=")+10); 2679 if(selector != null) { 2680 if(!selector.booleanValue()) { 2682 try { 2683 DataproviderObject_1_0 bundledProductPosition = this.plugin.retrieveObjectFromLocal( 2684 header, 2685 request.path().getPrefix(request.path().size()-3).getChild(positionId) 2686 ); 2687 this.removeContractPosition( 2688 header, 2689 bundledProductPosition, 2690 true 2691 ); 2692 } 2693 catch(ServiceException e) { 2694 if(e.getExceptionCode() != BasicException.Code.NOT_FOUND) { 2695 throw e; 2696 } 2697 } 2698 } 2699 } 2700 else { 2702 DataproviderObject_1_0 bundledProductPosition = this.plugin.retrieveObjectFromLocal( 2703 header, 2704 request.path().getPrefix(request.path().size()-3).getChild(positionId) 2705 ); 2706 if( 2707 (newValue.containsAttributeName("name") && !newValue.values("name").get(0).equals(bundledProductPosition.values("name").get(0))) || 2708 (newValue.containsAttributeName("description") && !newValue.values("description").get(0).equals(bundledProductPosition.values("description").get(0))) || 2709 (newValue.containsAttributeName("quantity") && (((BigDecimal )newValue.values("quantity").get(0)).compareTo(bundledProductPosition.values("quantity").get(0)) != 0)) 2710 ) { 2711 DataproviderObject modifiedBundledProductPosition = this.plugin.retrieveObjectForModification( 2712 request.path().getPrefix(request.path().size()-3).getChild(positionId) 2713 ); 2714 if(newValue.containsAttributeName("name")) { 2715 modifiedBundledProductPosition.clearValues("name").addAll( 2716 newValue.values("name") 2717 ); 2718 } 2719 if(newValue.containsAttributeName("description")) { 2720 modifiedBundledProductPosition.clearValues("description").addAll( 2721 newValue.values("description") 2722 ); 2723 } 2724 if(newValue.containsAttributeName("quantity")) { 2725 modifiedBundledProductPosition.clearValues("quantity").addAll( 2726 newValue.values("quantity") 2727 ); 2728 } 2729 } 2730 } 2731 } 2732 else if(NEW_BUNDLED_PRODUCT_POSITION.equals(command)) { 2733 if((selector != null) && selector.booleanValue()) { 2735 String parentId = selectableItemId.substring( 2736 selectableItemId.indexOf(":parent=")+8, 2737 selectableItemId.indexOf(":bundledProductId=") 2738 ); 2739 DataproviderObject_1_0 productBundlePosition = this.plugin.retrieveObjectFromLocal( 2740 header, 2741 request.path().getPrefix(request.path().size()-3).getChild(parentId) 2742 ); 2743 String bundledProductId = selectableItemId.substring( 2744 selectableItemId.indexOf(":bundledProductId=")+18 2745 ); 2746 DataproviderObject_1_0 productBundle = this.plugin.retrieveObjectFromLocal( 2747 header, 2748 (Path)productBundlePosition.values("basedOn").get(0) 2749 ); 2750 this.createBundledProductPosition( 2751 header, 2752 productBundlePosition.path(), 2753 productBundlePosition.path().getPrefix(productBundlePosition.path().size()-2), 2754 ((Path)productBundle.values("bundleType").get(0)).getDescendant(new String []{"bundledProduct", bundledProductId}), 2755 (BigDecimal )newValue.values("quantity").get(0) 2756 ); 2757 } 2758 } 2759 else if(MODIFY_CONFIGURATION.equals(command)) { 2760 String positionId = selectableItemId.substring( 2761 selectableItemId.indexOf(":position=")+10, 2762 selectableItemId.indexOf(":configId=") 2763 ); 2764 Path bundledProductPositionIdentity = 2765 request.path().getPrefix(request.path().size()-3).getChild(positionId); 2766 String configId = selectableItemId.substring( 2767 selectableItemId.indexOf(":configId=")+10 2768 ); 2769 Path configIdentity = bundledProductPositionIdentity.getDescendant( 2770 new String []{"configuration", configId} 2771 ); 2772 if(selector != null) { 2773 if(!selector.booleanValue()) { 2775 try { 2776 this.plugin.removeObject( 2777 configIdentity 2778 ); 2779 DataproviderObject bundledProductPosition = this.plugin.retrieveObjectForModification( 2780 bundledProductPositionIdentity 2781 ); 2782 if( 2783 (bundledProductPosition.getValues("currentConfig") != null) && 2784 configIdentity.equals(bundledProductPosition.values("currentConfig").get(0)) 2785 ) { 2786 bundledProductPosition.clearValues("currentConfig"); 2787 } 2788 } 2789 catch(ServiceException e) { 2790 if(e.getExceptionCode() != BasicException.Code.NOT_FOUND) { 2791 throw e; 2792 } 2793 } 2794 } 2795 } 2796 else { 2798 } 2800 } 2801 else if(NEW_CONFIGURATION.equals(command)) { 2802 if((selector != null) && selector.booleanValue()) { 2804 String parentId = selectableItemId.substring( 2805 selectableItemId.indexOf(":parent=")+8, 2806 selectableItemId.indexOf(":configId=") 2807 ); 2808 Path bundledProductPositionIdentity = 2809 request.path().getPrefix(request.path().size()-3).getChild(parentId); 2810 DataproviderObject bundledProductPosition = this.plugin.retrieveObjectForModification( 2811 bundledProductPositionIdentity 2812 ); 2813 String configId = selectableItemId.substring( 2814 selectableItemId.indexOf(":configId=")+10 2815 ); 2816 DataproviderObject_1_0 configuration = this.plugin.retrieveObjectFromLocal( 2817 header, 2818 ((Path)bundledProductPosition.values("basedOn").get(0)).getDescendant( 2819 new String []{"configuration", configId} 2820 ) 2821 ); 2822 DataproviderObject_1_0 newConfiguration = 2823 this.cloning.cloneAndUpdateReferences( 2824 header, 2825 configuration, 2826 bundledProductPositionIdentity.getChild("configuration"), 2827 null, 2828 "property", 2829 true 2830 ); 2831 bundledProductPosition.clearValues("currentConfig").add( 2832 newConfiguration.path() 2833 ); 2834 } 2835 } 2836 } 2837 2838 public Path updateInventory( 2840 ServiceHeader header, 2841 DataproviderObject_1_0 contract, 2842 Boolean cancelPreviousInventoryUpdate 2843 ) throws ServiceException { 2844 2845 if(contract.values("inventoryCb").size() > 0) { 2847 return null; 2848 } 2849 DataproviderObject_1_0 deliveryDepot = null; 2850 2851 List depotReferences = this.delegation.addFindRequest( 2854 contract.path().getChild("depotReference"), 2855 null, 2856 AttributeSelectors.ALL_ATTRIBUTES, 2857 0, 2858 Integer.MAX_VALUE, 2859 Directions.ASCENDING 2860 ); 2861 boolean hasDepotGoodsDelivery = false; 2862 for( 2863 Iterator j = depotReferences.iterator(); 2864 j.hasNext(); 2865 ) { 2866 DataproviderObject_1_0 depotReference = (DataproviderObject_1_0)j.next(); 2867 Number depotUsage = (Number )depotReference.values("depotUsage").get(0); 2868 if((depotUsage != null) && (depotUsage.shortValue() == Depots.DEPOT_USAGE_GOODS_DELIVERY)) { 2869 hasDepotGoodsDelivery = true; 2870 deliveryDepot = this.plugin.retrieveObjectFromLocal( 2871 header, 2872 (Path)depotReference.values("depot").get(0) 2873 ); 2874 } 2875 } 2876 if(!hasDepotGoodsDelivery) { 2877 throw new ServiceException( 2878 OpenCrxException.DOMAIN, 2879 OpenCrxException.CONTRACT_MISSING_DEPOT_GOODS_DELIVERY, 2880 new BasicException.Parameter[]{ 2881 new BasicException.Parameter("param0", contract.values("name").get(0)), 2882 }, 2883 "Missing goods delivery depot." 2884 ); 2885 } 2886 2887 List contractPositions = this.delegation.addFindRequest( 2891 contract.path().getChild("position"), 2892 null, 2893 AttributeSelectors.ALL_ATTRIBUTES, 2894 0, 2895 Integer.MAX_VALUE, 2896 Directions.ASCENDING 2897 ); 2898 2899 DataproviderObject_1_0[] issueDepotPositions = new DataproviderObject_1_0[contractPositions.size()]; 2901 DataproviderObject_1_0[] returnDepotPositions = new DataproviderObject_1_0[contractPositions.size()]; 2902 DataproviderObject_1_0[] deliveryDepotPositions = new DataproviderObject_1_0[contractPositions.size()]; 2903 int ii = 0; 2904 for( 2905 Iterator i = contractPositions.iterator(); 2906 i.hasNext(); 2907 ii++ 2908 ) { 2909 DataproviderObject_1_0 position = (DataproviderObject_1_0)i.next(); 2910 2911 depotReferences = this.delegation.addFindRequest( 2912 position.path().getChild("depotReference"), 2913 null, 2914 AttributeSelectors.ALL_ATTRIBUTES, 2915 0, 2916 Integer.MAX_VALUE, 2917 Directions.ASCENDING 2918 ); 2919 DataproviderObject_1_0 issueDepot = null; 2920 DataproviderObject_1_0 returnDepot = null; 2921 boolean holderQualifiesPosition = false; 2922 for( 2923 Iterator j = depotReferences.iterator(); 2924 j.hasNext(); 2925 ) { 2926 DataproviderObject_1_0 depotReference = (DataproviderObject_1_0)j.next(); 2927 Number depotUsage = (Number )depotReference.values("depotUsage").get(0); 2928 if((depotUsage != null) && (depotUsage.shortValue() == Depots.DEPOT_USAGE_GOODS_ISSUE)) { 2929 issueDepot = this.plugin.retrieveObjectFromLocal( 2930 header, 2931 (Path)depotReference.values("depot").get(0) 2932 ); 2933 holderQualifiesPosition = depotReference.values("holderQualifiesPosition").size() > 0 2935 ? ((Boolean )depotReference.values("holderQualifiesPosition").get(0)).booleanValue() 2936 : false; 2937 } 2938 if((depotUsage != null) && (depotUsage.shortValue() == Depots.DEPOT_USAGE_GOODS_RETURN)) { 2939 returnDepot = this.plugin.retrieveObjectFromLocal( 2940 header, 2941 (Path)depotReference.values("depot").get(0) 2942 ); 2943 } 2944 } 2945 if(issueDepot == null) { 2946 throw new ServiceException( 2947 OpenCrxException.DOMAIN, 2948 OpenCrxException.CONTRACT_MISSING_DEPOT_GOODS_ISSUE, 2949 new BasicException.Parameter[]{ 2950 new BasicException.Parameter("param0", position.values("lineItemNumber").get(0)), 2951 }, 2952 "Missing goods issue depot." 2953 ); 2954 } 2955 if(returnDepot == null) { 2956 throw new ServiceException( 2957 OpenCrxException.DOMAIN, 2958 OpenCrxException.CONTRACT_MISSING_DEPOT_GOODS_RETURN, 2959 new BasicException.Parameter[]{ 2960 new BasicException.Parameter("param0", position.values("lineItemNumber").get(0)), 2961 }, 2962 "Missing goods return depot." 2963 ); 2964 } 2965 2966 deliveryDepotPositions[ii] = 2968 this.plugin.depots.openDepotPosition( 2969 header, 2970 deliveryDepot, 2971 null, 2972 null, 2973 org.openmdx.base.text.format.DateFormat.getInstance().format(new Date ()), 2974 holderQualifiesPosition ? (String )position.values("positionNumber").get(0) : null, 2975 (Path)position.values("basedOn").get(0), 2976 null, 2977 Boolean.FALSE 2978 ); 2979 2980 issueDepotPositions[ii] = 2982 this.plugin.depots.openDepotPosition( 2983 header, 2984 issueDepot, 2985 null, 2986 null, 2987 org.openmdx.base.text.format.DateFormat.getInstance().format(new Date ()), 2988 holderQualifiesPosition ? (String )position.values("positionNumber").get(0) : null, 2989 (Path)position.values("basedOn").get(0), 2990 null, 2991 Boolean.FALSE 2992 ); 2993 2994 returnDepotPositions[ii] = 2996 this.plugin.depots.openDepotPosition( 2997 header, 2998 returnDepot, 2999 null, 3000 null, 3001 org.openmdx.base.text.format.DateFormat.getInstance().format(new Date ()), 3002 holderQualifiesPosition ? (String )position.values("positionNumber").get(0) : null, 3003 (Path)position.values("basedOn").get(0), 3004 null, 3005 Boolean.FALSE 3006 ); 3007 } 3008 3009 Path[] creditPositions = new Path[contractPositions.size()]; 3011 Path[] debitPositions = new Path[contractPositions.size()]; 3012 BigDecimal [] quantities = new BigDecimal [contractPositions.size()]; 3013 String [] bookingTextNames = new String [contractPositions.size()]; 3014 Path[] productConfigurationSets = new Path[contractPositions.size()]; 3015 Path[] originIdentities = new Path[contractPositions.size()]; 3016 3017 ii = 0; 3018 for( 3019 Iterator i = contractPositions.iterator(); 3020 i.hasNext(); 3021 ii++ 3022 ) { 3023 DataproviderObject_1_0 contractPosition = (DataproviderObject_1_0)i.next(); 3024 BigDecimal quantity = (BigDecimal )contractPosition.values("quantity").get(0); 3025 if(quantity.compareTo(new BigDecimal (0)) < 0) { 3026 creditPositions[ii] = returnDepotPositions[ii].path(); 3027 debitPositions[ii] = deliveryDepotPositions[ii].path(); 3028 bookingTextNames[ii] = BOOKING_TEXT_NAME_RETURN_GOODS; 3029 } 3030 else { 3031 creditPositions[ii] = deliveryDepotPositions[ii].path(); 3032 debitPositions[ii] = issueDepotPositions[ii].path(); 3033 bookingTextNames[ii] = BOOKING_TEXT_NAME_DELIVER_GOODS; 3034 } 3035 String contractPositionType = (String )contractPosition.values(SystemAttributes.OBJECT_CLASS).get(0); 3036 if(this.model.isSubtypeOf(contractPositionType, "org:opencrx:kernel:product1:ProductInUseDescriptor")) { 3037 productConfigurationSets[ii] = contractPosition.path(); 3038 } 3039 originIdentities[ii] = contractPosition.path(); 3040 quantities[ii] = quantity.abs(); 3041 } 3042 DataproviderObject_1_0 booking = this.plugin.depots.createCompoundBooking( 3043 header, 3044 deliveryDepot.path().getPrefix(7), 3045 org.openmdx.base.text.format.DateFormat.getInstance().format(new Date ()), 3046 Depots.BOOKING_TYPE_STANDARD, 3047 quantities, 3048 bookingTextNames, 3049 null, 3050 creditPositions, 3051 debitPositions, 3052 productConfigurationSets, 3053 originIdentities, 3054 null 3055 ); 3056 3057 DataproviderObject modifiedContract = this.plugin.retrieveObjectForModification(contract.path()); 3058 modifiedContract.clearValues("inventoryCb").add(booking.path()); 3059 3060 return booking.path(); 3061 } 3062 3063 public void cancelInventoryUpdate( 3065 ServiceHeader header, 3066 DataproviderObject_1_0 contract 3067 ) throws ServiceException { 3068 if(contract.values("inventoryCb").size() > 0) { 3069 this.plugin.depots.removeCompoundBooking( 3070 header, 3071 (Path)contract.values("inventoryCb").get(0) 3072 ); 3073 DataproviderObject modifiedContract = this.plugin.retrieveObjectForModification(contract.path()); 3074 modifiedContract.clearValues("inventoryCb"); 3075 } 3076 } 3077 3078 public void updateContractPosition( 3080 ServiceHeader header, 3081 DataproviderObject object, 3082 DataproviderObject_1_0 oldValues 3083 ) throws ServiceException { 3084 String objectClass = (String )object.values(SystemAttributes.OBJECT_CLASS).get(0); 3085 if(this.model.isSubtypeOf(objectClass, "org:opencrx:kernel:contract1:ContractPosition")) { 3086 Path productIdentity = (object.getValues("product") != null) && (object.values("product").size() > 0) 3087 ? (Path)object.values("product").get(0) 3088 : (Path)oldValues.values("product").get(0); 3089 if(productIdentity != null) { 3090 DataproviderObject_1_0 product = this.plugin.retrieveObjectFromDelegation(productIdentity); 3091 DataproviderObject_1_0 contract = this.plugin.retrieveObjectFromLocal( 3092 header, 3093 object.path().getParent().getParent() 3094 ); 3095 this.updateContractPosition( 3096 header, 3097 contract, 3098 object, 3099 oldValues, 3100 product, 3101 false 3102 ); 3103 } 3104 } 3105 } 3106 3107 public void repriceContractPosition( 3109 ServiceHeader header, 3110 DataproviderObject_1_0 object 3111 ) throws ServiceException { 3112 String objectClass = (String )object.values(SystemAttributes.OBJECT_CLASS).get(0); 3113 if(this.model.isSubtypeOf(objectClass, "org:opencrx:kernel:contract1:ContractPosition")) { 3114 Path productIdentity = (Path)object.values("product").get(0); 3115 if(productIdentity != null) { 3116 DataproviderObject_1_0 product = this.plugin.retrieveObjectFromDelegation(productIdentity); 3117 DataproviderObject_1_0 contract = this.plugin.retrieveObjectFromLocal( 3118 header, 3119 object.path().getParent().getParent() 3120 ); 3121 DataproviderObject position = this.plugin.retrieveObjectForModification( 3122 object.path() 3123 ); 3124 position.attributeNames().remove("priceLevel"); 3126 this.updateContractPosition( 3127 header, 3128 contract, 3129 position, 3130 object, 3131 product, 3132 true 3133 ); 3134 } 3135 } 3136 } 3137 3138 public void repriceContract( 3140 ServiceHeader header, 3141 DataproviderObject_1_0 object 3142 ) throws ServiceException { 3143 String objectClass = (String )object.values(SystemAttributes.OBJECT_CLASS).get(0); 3144 if(this.model.isSubtypeOf(objectClass, "org:opencrx:kernel:contract1:AbstractContract")) { 3145 List positions = this.delegation.addFindRequest( 3146 object.path().getChild("position"), 3147 null, 3148 AttributeSelectors.ALL_ATTRIBUTES, 3149 0, 3150 Integer.MAX_VALUE, 3151 Directions.ASCENDING 3152 ); 3153 for(Iterator i = positions.iterator(); i.hasNext(); ) { 3154 this.repriceContractPosition( 3155 header, 3156 (DataproviderObject_1_0)i.next() 3157 ); 3158 } 3159 } 3160 } 3161 3162 public void replaceContractPosition( 3164 ServiceHeader header, 3165 DataproviderRequest request 3166 ) throws ServiceException { 3167 if(request.object().getValues("pricePerUnit") != null) { 3169 DataproviderObject newValues = request.object(); 3170 DataproviderObject position = this.plugin.retrieveObjectForModification(request.path()); 3171 boolean priceIsModified = (newValues.getValues("pricePerUnit") == null) || (position.getValues("pricePerUnit") == null) 3172 ? newValues.values("pricePerUnit").get(0) != position.values("pricePerUnit").get(0) 3173 : ((BigDecimal )newValues.values("pricePerUnit").get(0)).compareTo((BigDecimal )position.values("pricePerUnit").get(0)) != 0; 3174 if(priceIsModified) { 3175 position.clearValues("pricingState").add( 3176 new Short (PRICING_STATE_DIRTY) 3177 ); 3178 } 3179 } 3180 } 3181 3182 private static final String DEFAULT_REFERENCE_FILTER = ":*, :*/:*/:*, :*/:*/:*/:*/:*"; 3186 3187 private final static int BATCHING_MODE_SIZE = 1000; 3188 3189 private static final short CLOSED_THRESHOLD_LEAD = 1110; 3191 private static final short CLOSED_THRESHOLD_OPPORTUNITY = 1210; 3192 private static final short CLOSED_THRESHOLD_QUOTE = 1310; 3193 private static final short CLOSED_THRESHOLD_SALES_ORDER = 1410; 3194 private static final short CLOSED_THRESHOLD_INVOICE = 1510; 3195 3196 private static final int MIN_MAX_QUANTITY_HANDLING_NA = 0; 3198 private static final int MIN_MAX_QUANTITY_HANDLING_INFORMATIONAL = 1; 3199 private static final int MIN_MAX_QUANTITY_HANDLING_STRICT = 2; 3200 private static final int MIN_MAX_QUANTITY_HANDLING_LIMIT = 3; 3201 3202 private static final short PRICING_STATE_DIRTY = 10; 3204 private static final short PRICING_STATE_OK = 20; 3205 3206 private static final String MODIFY_PRODUCT_BUNDLE_POSITION = "MODIFY_BUNDLE"; 3208 private static final String NEW_PRODUCT_BUNDLE_POSITION = "NEW_BUNDLE"; 3209 private static final String MODIFY_BUNDLED_PRODUCT_POSITION = "MODIFY_BUNDLED_PRODUCT"; 3210 private static final String NEW_BUNDLED_PRODUCT_POSITION = "NEW_BUNDLED_PRODUCT"; 3211 private static final String MODIFY_CONFIGURATION = "MODIFY_CONFIG"; 3212 private static final String NEW_CONFIGURATION = "NEW_CONFIG"; 3213 3214 private static final String BOOKING_TEXT_NAME_RETURN_GOODS = "return goods"; 3216 private static final String BOOKING_TEXT_NAME_DELIVER_GOODS = "deliver goods"; 3217 3218 private final Model_1_0 model; 3219 private final OpenCrxKernel_1 plugin; 3220 private final RequestCollection delegation; 3221 private final RefPackage_1_0 rootPkg; 3222 private final Cloneable cloning; 3223 private final Map cachedObjects = new HashMap (); 3224 private final Map cachedDescriptions = new HashMap (); 3225 3226} 3227 3228 | Popular Tags |