KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opencrx > kernel > layer > application > Products


1 /*
2  * ====================================================================
3  * Project: opencrx, http://www.opencrx.org/
4  * Name: $Id: Products.java,v 1.13 2006/03/23 00:55:42 wfro Exp $
5  * Description: openCRX application plugin
6  * Revision: $Revision: 1.13 $
7  * Owner: CRIXP AG, Switzerland, http://www.crixp.com
8  * Date: $Date: 2006/03/23 00:55:42 $
9  * ====================================================================
10  *
11  * This software is published under the BSD license
12  * as listed below.
13  *
14  * Copyright (c) 2004-2005, CRIXP Corp., Switzerland
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions
19  * are met:
20  *
21  * * Redistributions of source code must retain the above copyright
22  * notice, this list of conditions and the following disclaimer.
23  *
24  * * Redistributions in binary form must reproduce the above copyright
25  * notice, this list of conditions and the following disclaimer in
26  * the documentation and/or other materials provided with the
27  * distribution.
28  *
29  * * Neither the name of CRIXP Corp. nor the names of the contributors
30  * to openCRX may be used to endorse or promote products derived
31  * from this software without specific prior written permission
32  *
33  *
34  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
35  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
36  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
37  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
39  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
40  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
41  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
43  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
45  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46  * POSSIBILITY OF SUCH DAMAGE.
47  *
48  * ------------------
49  *
50  * This product includes software developed by the Apache Software
51  * Foundation (http://www.apache.org/).
52  *
53  * This product includes software developed by contributors to
54  * openMDX (http://www.openmdx.org/)
55  */

56 package org.opencrx.kernel.layer.application;
57
58 import java.lang.reflect.InvocationTargetException JavaDoc;
59 import java.lang.reflect.Method JavaDoc;
60 import java.math.BigDecimal JavaDoc;
61 import java.text.ParseException JavaDoc;
62 import java.util.ArrayList JavaDoc;
63 import java.util.Arrays JavaDoc;
64 import java.util.Date JavaDoc;
65 import java.util.HashMap JavaDoc;
66 import java.util.HashSet JavaDoc;
67 import java.util.Iterator JavaDoc;
68 import java.util.List JavaDoc;
69 import java.util.Map JavaDoc;
70
71 import org.codehaus.janino.ClassBodyEvaluator;
72 import org.codehaus.janino.CompileException;
73 import org.codehaus.janino.Parser;
74 import org.codehaus.janino.Scanner;
75 import org.opencrx.kernel.generic.OpenCrxException;
76 import org.openmdx.base.accessor.jmi.cci.RefPackage_1_0;
77 import org.openmdx.base.exception.ServiceException;
78 import org.openmdx.compatibility.base.dataprovider.cci.AttributeSelectors;
79 import org.openmdx.compatibility.base.dataprovider.cci.DataproviderObject;
80 import org.openmdx.compatibility.base.dataprovider.cci.DataproviderObject_1_0;
81 import org.openmdx.compatibility.base.dataprovider.cci.Directions;
82 import org.openmdx.compatibility.base.dataprovider.cci.RequestCollection;
83 import org.openmdx.compatibility.base.dataprovider.cci.ServiceHeader;
84 import org.openmdx.compatibility.base.dataprovider.cci.SystemAttributes;
85 import org.openmdx.compatibility.base.marshalling.Marshaller;
86 import org.openmdx.compatibility.base.naming.Path;
87 import org.openmdx.compatibility.base.query.FilterOperators;
88 import org.openmdx.compatibility.base.query.FilterProperty;
89 import org.openmdx.compatibility.base.query.Quantors;
90 import org.openmdx.kernel.exception.BasicException;
91 import org.openmdx.model1.accessor.basic.cci.Model_1_0;
92
93 public class Products {
94
95     //-----------------------------------------------------------------------
96
public Products(
97         Model_1_0 model,
98         OpenCrxKernel_1 plugin,
99         RequestCollection delegation,
100         RefPackage_1_0 rootPkg
101     ) {
102         this.model = model;
103         this.plugin = plugin;
104         this.delegation = delegation;
105         this.rootPkg = rootPkg;
106     }
107
108     //-------------------------------------------------------------------------
109
public void cloneProductConfigurationSet(
110         ServiceHeader header,
111         Path fromIdentity,
112         Path toIdentity,
113         boolean cloneDefaultOnly,
114         boolean updateCurrentConfig
115     ) throws ServiceException {
116         List JavaDoc configurations = this.delegation.addFindRequest(
117             fromIdentity.getChild("configuration"),
118             null,
119             AttributeSelectors.ALL_ATTRIBUTES,
120             0,
121             Integer.MAX_VALUE,
122             Directions.ASCENDING
123         );
124         for(
125             Iterator JavaDoc i = configurations.iterator();
126             i.hasNext();
127         ) {
128             DataproviderObject_1_0 configuration = (DataproviderObject_1_0)i.next();
129             if(
130                 !cloneDefaultOnly ||
131                 ((configuration.values("isDefault").size() > 0) && ((Boolean JavaDoc)configuration.values("isDefault").get(0)).booleanValue())
132             ) {
133                 this.plugin.cloneable.cloneAndUpdateReferences(
134                     header,
135                     configuration,
136                     toIdentity.getChild("configuration"),
137                     null,
138                     "property",
139                     true
140                 );
141             }
142         }
143         // configType
144
DataproviderObject_1_0 from = this.plugin.retrieveObjectFromLocal(header, fromIdentity);
145         DataproviderObject to = this.plugin.retrieveObjectForModification(toIdentity);
146         to.clearValues("configType").addAll(
147             from.values("configType")
148         );
149         
150         // currentConfig
151
if(updateCurrentConfig) {
152             // Set current configuration to default config
153
configurations = this.delegation.addFindRequest(
154                 toIdentity.getChild("configuration"),
155                 null,
156                 AttributeSelectors.ALL_ATTRIBUTES,
157                 0,
158                 Integer.MAX_VALUE,
159                 Directions.ASCENDING
160             );
161             Path defaultConfigurationIdentity = null;
162             for(
163                 Iterator JavaDoc i = configurations.iterator();
164                 i.hasNext();
165             ) {
166                 DataproviderObject_1_0 configuration = (DataproviderObject_1_0)i.next();
167                 if((configuration.values("isDefault").size() > 0) && ((Boolean JavaDoc)configuration.values("isDefault").get(0)).booleanValue()) {
168                     defaultConfigurationIdentity = configuration.path();
169                     break;
170                 }
171             }
172             if(defaultConfigurationIdentity != null) {
173                 to.clearValues("currentConfig").add(defaultConfigurationIdentity);
174             }
175         }
176     }
177     
178     //-------------------------------------------------------------------------
179
public void setConfigurationType(
180         ServiceHeader header,
181         DataproviderObject_1_0 product,
182         Path configurationTypeIdentity
183     ) throws ServiceException {
184         this.plugin.removeAll(
185             product.path().getChild("configuration"),
186             null,
187             0,
188             new HashSet JavaDoc()
189         );
190         List JavaDoc configurationTypes = this.delegation.addFindRequest(
191             configurationTypeIdentity.getChild("configurationType"),
192             null,
193             AttributeSelectors.ALL_ATTRIBUTES,
194             0,
195             Integer.MAX_VALUE,
196             Directions.ASCENDING
197         );
198         Map JavaDoc objectMarshallers = new HashMap JavaDoc();
199         objectMarshallers.put(
200             "org:opencrx:kernel:product1:ProductConfigurationType",
201             new Marshaller() {
202                 public Object JavaDoc marshal(Object JavaDoc s) throws ServiceException {
203                     DataproviderObject configuration = new DataproviderObject(
204                         (DataproviderObject_1_0)s
205                     );
206                     configuration.clearValues(
207                         SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:product1:ProductConfiguration"
208                     );
209                     return configuration;
210                 }
211                 public Object JavaDoc unmarshal(Object JavaDoc s) {
212                     throw new UnsupportedOperationException JavaDoc();
213                 }
214             }
215         );
216         for(
217             Iterator JavaDoc i = configurationTypes.iterator();
218             i.hasNext();
219         ) {
220             DataproviderObject_1_0 configurationType = (DataproviderObject_1_0)i.next();
221             DataproviderObject configuration =
222                 this.plugin.cloneable.cloneAndUpdateReferences(
223                     header,
224                     configurationType,
225                     product.path().getChild("configuration"),
226                     objectMarshallers,
227                     "property",
228                     true
229                 );
230             configuration = this.plugin.retrieveObjectForModification(configuration.path());
231             configuration.clearValues("configType").add(
232                 configurationType.path()
233             );
234         }
235         DataproviderObject modifiedProduct = this.plugin.retrieveObjectForModification(product.path());
236         modifiedProduct.clearValues("configType").add(
237             configurationTypeIdentity
238         );
239     }
240     
241     //-------------------------------------------------------------------------
242
public void unsetConfigurationType(
243         DataproviderObject_1_0 product
244     ) throws ServiceException {
245         
246     }
247     
248     //-------------------------------------------------------------------------
249
public void assignProduct(
250         ServiceHeader header,
251         DataproviderObject_1_0 bundledProduct,
252         Path productIdentity
253     ) throws ServiceException {
254         DataproviderObject modifiedBundledProduct = this.plugin.retrieveObjectForModification(bundledProduct.path());
255         modifiedBundledProduct.clearValues("product").add(
256             productIdentity
257         );
258         DataproviderObject_1_0 product = this.plugin.retrieveObjectFromLocal(
259             header,
260             productIdentity
261         );
262         modifiedBundledProduct.clearValues("configType").addAll(
263             product.values("configType")
264         );
265         // Remove existing configuration
266
this.plugin.removeAll(
267             bundledProduct.path().getChild("configuration"),
268             null,
269             0,
270             new HashSet JavaDoc()
271         );
272         this.cloneProductConfigurationSet(
273             header,
274             productIdentity,
275             bundledProduct.path(),
276             false,
277             true
278         );
279         // Remove existing depotReference
280
this.plugin.removeAll(
281             bundledProduct.path().getChild("depotReference"),
282             null,
283             0,
284             new HashSet JavaDoc()
285         );
286         // Copy depot references from product
287
List JavaDoc depotReferences = this.delegation.addFindRequest(
288             productIdentity.getChild("depotReference"),
289             null,
290             AttributeSelectors.ALL_ATTRIBUTES,
291             0,
292             Integer.MAX_VALUE,
293             Directions.ASCENDING
294         );
295         for(
296             Iterator JavaDoc i = depotReferences.iterator();
297             i.hasNext();
298         ) {
299             DataproviderObject_1_0 depotReference = (DataproviderObject_1_0)i.next();
300             this.plugin.cloneable.cloneAndUpdateReferences(
301                 header,
302                 depotReference,
303                 bundledProduct.path().getChild("depotReference"),
304                 null,
305                 "",
306                 true
307             );
308         }
309     }
310     
311     //-------------------------------------------------------------------------
312
public FilterProperty[] getProductFilterProperties(
313         Path productFilterIdentity
314     ) throws ServiceException {
315         List JavaDoc filterProperties = this.delegation.addFindRequest(
316             productFilterIdentity.getChild("productFilterProperty"),
317             null,
318             AttributeSelectors.ALL_ATTRIBUTES,
319             null,
320             0,
321             Integer.MAX_VALUE,
322             Directions.ASCENDING
323         );
324         List JavaDoc filter = new ArrayList JavaDoc();
325         for(
326             Iterator JavaDoc i = filterProperties.iterator();
327             i.hasNext();
328         ) {
329             DataproviderObject_1_0 filterProperty = (DataproviderObject_1_0)i.next();
330             String JavaDoc filterPropertyClass = (String JavaDoc)filterProperty.values(SystemAttributes.OBJECT_CLASS).get(0);
331
332             Boolean JavaDoc isActive = (Boolean JavaDoc)filterProperty.values("isActive").get(0);
333             
334             if((isActive != null) && isActive.booleanValue()) {
335                 // Get filterOperator, filterQuantor
336
short filterOperator = filterProperty.values("filterOperator").size() == 0
337                     ? FilterOperators.IS_IN
338                     : ((Number JavaDoc)filterProperty.values("filterOperator").get(0)).shortValue();
339                 filterOperator = filterOperator == 0
340                     ? FilterOperators.IS_IN
341                     : filterOperator;
342                 short filterQuantor = filterProperty.values("filterQuantor").size() == 0
343                     ? Quantors.THERE_EXISTS
344                     : ((Number JavaDoc)filterProperty.values("filterQuantor").get(0)).shortValue();
345                 filterQuantor = filterQuantor == 0
346                     ? Quantors.THERE_EXISTS
347                     : filterQuantor;
348                 
349                 if("org:opencrx:kernel:product1:ProductTypeFilterProperty".equals(filterPropertyClass)) {
350                     filter.add(
351                         new FilterProperty(
352                             filterQuantor,
353                             "productType",
354                             filterOperator,
355                             filterProperty.values("productType").toArray()
356                         )
357                     );
358                 }
359                 else if("org:opencrx:kernel:product1:DefaultSalesTaxTypeFilterProperty".equals(filterPropertyClass)) {
360                     filter.add(
361                         new FilterProperty(
362                             filterQuantor,
363                             "salesTaxType",
364                             filterOperator,
365                             filterProperty.values("salesTaxType").toArray()
366                         )
367                     );
368                 }
369                 else if("org:opencrx:kernel:product1:CategoryFilterProperty".equals(filterPropertyClass)) {
370                     filter.add(
371                         new FilterProperty(
372                             filterQuantor,
373                             "category",
374                             filterOperator,
375                             filterProperty.values("category").toArray()
376                         )
377                     );
378                 }
379                 else if("org:opencrx:kernel:product1:PriceUomFilterProperty".equals(filterPropertyClass)) {
380                     filter.add(
381                         new FilterProperty(
382                             filterQuantor,
383                             "priceUom",
384                             filterOperator,
385                             filterProperty.values("priceUom").toArray()
386                         )
387                     );
388                 }
389             }
390         }
391         return (FilterProperty[])filter.toArray(new FilterProperty[filter.size()]);
392     }
393
394     //-------------------------------------------------------------------------
395
private List JavaDoc getAssignedPriceListEntries(
396         DataproviderObject_1_0 priceLevel
397     ) throws ServiceException {
398         List JavaDoc priceFilter = new ArrayList JavaDoc();
399         priceFilter.add(
400             new FilterProperty(
401                 Quantors.THERE_EXISTS,
402                 "priceLevel",
403                 FilterOperators.IS_IN,
404                 new Object JavaDoc[]{priceLevel.path()}
405             )
406         );
407         return this.delegation.addFindRequest(
408             priceLevel.path().getPrefix(5).getChild("priceListEntry"),
409             (FilterProperty[])priceFilter.toArray(new FilterProperty[priceFilter.size()]),
410             AttributeSelectors.ALL_ATTRIBUTES,
411             0,
412             BATCHING_MODE_SIZE,
413             Directions.ASCENDING
414         );
415     }
416     
417     //-------------------------------------------------------------------------
418
private List JavaDoc findPrices(
419         DataproviderObject_1_0 priceLevel,
420         boolean useBasedOnPriceLevel,
421         Path productIdentity
422     ) throws ServiceException {
423         List JavaDoc priceFilter = new ArrayList JavaDoc();
424         
425         // priceCurrency
426
if(priceLevel.values("priceCurrency").size() > 0) {
427             priceFilter.add(
428                 new FilterProperty(
429                     Quantors.THERE_EXISTS,
430                     "priceCurrency",
431                     FilterOperators.IS_IN,
432                     priceLevel.values("priceCurrency").toArray()
433                 )
434             );
435         }
436         // priceUsage
437
if(priceLevel.values("priceUsage").size() > 0) {
438             priceFilter.add(
439                 new FilterProperty(
440                     Quantors.THERE_EXISTS,
441                     "usage",
442                     FilterOperators.IS_IN,
443                     priceLevel.values("priceUsage").toArray()
444                 )
445             );
446         }
447         // priceLevel
448
if(useBasedOnPriceLevel) {
449             if(priceLevel.values("basedOn").size() > 0) {
450                 priceFilter.add(
451                     new FilterProperty(
452                         Quantors.THERE_EXISTS,
453                         "priceLevel",
454                         FilterOperators.IS_IN,
455                         priceLevel.values("basedOn").toArray()
456                     )
457                 );
458             }
459         }
460         else {
461             priceFilter.add(
462                 new FilterProperty(
463                     Quantors.THERE_EXISTS,
464                     "priceLevel",
465                     FilterOperators.IS_IN,
466                     new Object JavaDoc[]{priceLevel.path()}
467                 )
468             );
469         }
470         return this.delegation.addFindRequest(
471             productIdentity.getChild("basePrice"),
472             (FilterProperty[])priceFilter.toArray(new FilterProperty[priceFilter.size()]),
473             AttributeSelectors.ALL_ATTRIBUTES,
474             0,
475             BATCHING_MODE_SIZE,
476             Directions.ASCENDING
477         );
478     }
479     
480     //-------------------------------------------------------------------------
481
public int movePricesFromBasedOnPriceLevel(
482         ServiceHeader header,
483         DataproviderObject_1_0 priceLevel,
484         DataproviderObject_1_0 params
485     ) throws ServiceException {
486         if(
487             ((priceLevel.values("isFinal").size() > 0) &&
488             ((Boolean JavaDoc)priceLevel.values("isFinal").get(0)).booleanValue()) ||
489             (priceLevel.values("basedOn").size() > 0)
490         ) {
491             throw new ServiceException(
492                 OpenCrxException.DOMAIN,
493                 OpenCrxException.PRODUCT_OPERATION_NOT_ALLOWED_FOR_NON_BASIC_PRICE_LEVEL,
494                 new BasicException.Parameter[]{
495                     new BasicException.Parameter("param0", priceLevel.path())
496                 },
497                 "Operation is not allowed for final and non-basic price level."
498             );
499         }
500         short processingMode = params.values("processingMode").size() > 0
501             ? ((Short JavaDoc)params.values("processingMode").get(0)).shortValue()
502             : 0;
503             
504         // Get all products matching the product filter
505
List JavaDoc productFilter = new ArrayList JavaDoc();
506         productFilter.addAll(
507             Arrays.asList(
508                 this.getProductFilterProperties(
509                     priceLevel.path()
510                 )
511             )
512         );
513         List JavaDoc filteredProducts = this.delegation.addFindRequest(
514             priceLevel.path().getPrefix(5).getChild("allProduct"),
515             (FilterProperty[])productFilter.toArray(new FilterProperty[productFilter.size()]),
516             AttributeSelectors.ALL_ATTRIBUTES,
517             0,
518             BATCHING_MODE_SIZE,
519             Directions.ASCENDING
520         );
521         int numberProcessed = 0;
522         for(
523             Iterator JavaDoc i = filteredProducts.iterator();
524             i.hasNext();
525         ) {
526             DataproviderObject_1_0 product = (DataproviderObject_1_0)i.next();
527             Path productIdentity = new Path((String JavaDoc)product.values(SystemAttributes.OBJECT_IDENTITY).get(0));
528             List JavaDoc filteredPrices = this.findPrices(
529                 priceLevel,
530                 true,
531                 productIdentity
532             );
533             Map JavaDoc cachedPriceLevels = new HashMap JavaDoc();
534             for(
535                 Iterator JavaDoc j = filteredPrices.iterator();
536                 j.hasNext();
537             ) {
538                 DataproviderObject_1_0 price = (DataproviderObject_1_0)j.next();
539                 if(price.values("priceLevel").size() > 0) {
540                     DataproviderObject_1_0 cachedPriceLevel =
541                         (DataproviderObject_1_0)cachedPriceLevels.get(price.values("priceLevel").get(0));
542                     if(cachedPriceLevel == null) {
543                         cachedPriceLevels.put(
544                             price.values("priceLevel").get(0),
545                             cachedPriceLevel = this.plugin.retrieveObjectFromDelegation(
546                                 (Path)price.values("priceLevel").get(0)
547                             )
548                         );
549                     }
550                     if(
551                         (cachedPriceLevel.values("isFinal").size() > 0) &&
552                         ((Boolean JavaDoc)cachedPriceLevel.values("isFinal").get(0)).booleanValue()
553                     ) {
554                         continue;
555                     }
556                 }
557                 if(processingMode == PROCESSING_MODE_PROCESS) {
558                     DataproviderObject movedPrice = this.plugin.retrieveObjectForModification(
559                         price.path()
560                     );
561                     movedPrice.clearValues("priceLevel").add(
562                         priceLevel.path()
563                     );
564                 }
565                 numberProcessed++;
566             }
567         }
568         return numberProcessed;
569     }
570
571     //-------------------------------------------------------------------------
572
public int createPricesFromBasedOnPriceLevel(
573         ServiceHeader header,
574         DataproviderObject_1_0 priceLevel,
575         DataproviderObject_1_0 params
576     ) throws ServiceException {
577         if(
578             ((priceLevel.values("isFinal").size() > 0) &&
579             ((Boolean JavaDoc)priceLevel.values("isFinal").get(0)).booleanValue()) ||
580             (priceLevel.values("basedOn").size() == 0)
581         ) {
582             throw new ServiceException(
583                 OpenCrxException.DOMAIN,
584                 OpenCrxException.PRODUCT_OPERATION_NOT_ALLOWED_FOR_FINAL_PRICE_LEVEL,
585                 new BasicException.Parameter[]{
586                     new BasicException.Parameter("param0", priceLevel.path())
587                 },
588                 "Operation is not allowed for final price level."
589             );
590         }
591         if(
592             (priceLevel.values("basedOn").size() == 0)
593         ) {
594             throw new ServiceException(
595                 OpenCrxException.DOMAIN,
596                 OpenCrxException.PRODUCT_OPERATION_NOT_ALLOWED_FOR_BASIC_PRICE_LEVEL,
597                 new BasicException.Parameter[]{
598                     new BasicException.Parameter("param0", priceLevel.path())
599                 },
600                 "Operation is not allowed for basic price level."
601             );
602         }
603         List JavaDoc priceModifiers = this.delegation.addFindRequest(
604             priceLevel.path().getChild("priceModifier"),
605             null,
606             AttributeSelectors.ALL_ATTRIBUTES,
607             0,
608             BATCHING_MODE_SIZE,
609             Directions.ASCENDING
610         );
611         short processingMode = params.values("processingMode").size() > 0
612             ? ((Short JavaDoc)params.values("processingMode").get(0)).shortValue()
613             : 0;
614             
615         // Get all products matching the product filter
616
List JavaDoc productFilter = new ArrayList JavaDoc();
617         productFilter.addAll(
618             Arrays.asList(
619                 this.getProductFilterProperties(
620                     priceLevel.path()
621                 )
622             )
623         );
624         List JavaDoc filteredProducts = this.delegation.addFindRequest(
625             priceLevel.path().getPrefix(5).getChild("allProduct"),
626             (FilterProperty[])productFilter.toArray(new FilterProperty[productFilter.size()]),
627             AttributeSelectors.ALL_ATTRIBUTES,
628             0,
629             BATCHING_MODE_SIZE,
630             Directions.ASCENDING
631         );
632         int numberProcessed = 0;
633         // Iterate all matching products and create new prices
634
for(
635             Iterator JavaDoc i = filteredProducts.iterator();
636             i.hasNext();
637         ) {
638             DataproviderObject_1_0 product = (DataproviderObject_1_0)i.next();
639             Path productIdentity = new Path((String JavaDoc)product.values(SystemAttributes.OBJECT_IDENTITY).get(0));
640             List JavaDoc filteredPrices = this.findPrices(
641                 priceLevel,
642                 true,
643                 productIdentity
644             );
645             for(
646                 Iterator JavaDoc j = filteredPrices.iterator();
647                 j.hasNext();
648             ) {
649                 DataproviderObject_1_0 basePrice = (DataproviderObject_1_0)j.next();
650                 if(processingMode == PROCESSING_MODE_PROCESS) {
651                     DataproviderObject createdPrice = new DataproviderObject(
652                         basePrice.path().getParent().getChild(this.plugin.getUidAsString())
653                     );
654                     createdPrice.addClones(
655                         basePrice,
656                         true
657                     );
658                     BigDecimal JavaDoc quantityFromPrice = (BigDecimal JavaDoc)createdPrice.values("quantityFrom").get(0);
659                     BigDecimal JavaDoc quantityToPrice = (BigDecimal JavaDoc)createdPrice.values("quantityTo").get(0);
660                     for(
661                         Iterator JavaDoc k = priceModifiers.iterator();
662                         k.hasNext();
663                     ) {
664                         DataproviderObject_1_0 priceModifier = (DataproviderObject_1_0)k.next();
665                         BigDecimal JavaDoc quantityFromModifier = (BigDecimal JavaDoc)priceModifier.values("quantityFrom").get(0);
666                         quantityFromModifier = quantityFromModifier == null ? quantityFromPrice : quantityFromModifier;
667                         BigDecimal JavaDoc quantityToModifier = (BigDecimal JavaDoc)priceModifier.values("quantityTo").get(0);
668                         quantityToModifier = quantityToModifier == null ? quantityToPrice : quantityToModifier;
669                         // Apply modifier if quantity range is larger than the price quantity range
670
if(
671                             ((quantityFromModifier == null) || (quantityFromModifier.compareTo(quantityFromPrice) <= 0)) &&
672                             ((quantityToModifier == null) || (quantityToModifier.compareTo(quantityToPrice) >= 0))
673                         ) {
674                             String JavaDoc modifierType = (String JavaDoc)priceModifier.values(SystemAttributes.OBJECT_CLASS).get(0);
675                             if("org:opencrx:kernel:product1:DiscountPriceModifier".equals(modifierType)) {
676                                 boolean discountIsPercentageModifier =
677                                     (priceModifier.values("discountIsPercentage").size() > 0) &&
678                                     ((Boolean JavaDoc)priceModifier.values("discountIsPercentage").get(0)).booleanValue();
679                                 boolean discountIsPercentagePrice =
680                                     (createdPrice.values("discountIsPercentage").size() > 0) &&
681                                     ((Boolean JavaDoc)createdPrice.values("discountIsPercentage").get(0)).booleanValue();
682                                 if(discountIsPercentageModifier == discountIsPercentagePrice) {
683                                     createdPrice.clearValues("discount").addAll(
684                                         priceModifier.values("discount")
685                                     );
686                                 }
687                             }
688                             else if("org:opencrx:kernel:product1:LinearPriceModifier".equals(modifierType)) {
689                                 BigDecimal JavaDoc priceMultiplier = (BigDecimal JavaDoc)priceModifier.values("priceMultiplier").get(0);
690                                 priceMultiplier = priceMultiplier == null ? new BigDecimal JavaDoc(0) : priceMultiplier;
691                                 BigDecimal JavaDoc priceOffset = (BigDecimal JavaDoc)priceModifier.values("priceOffset").get(0);
692                                 priceOffset = priceOffset == null ? new BigDecimal JavaDoc(0) : priceOffset;
693                                 BigDecimal JavaDoc roundingFactor = (BigDecimal JavaDoc)priceModifier.values("roundingFactor").get(0);
694                                 roundingFactor = roundingFactor == null ? new BigDecimal JavaDoc(1) : roundingFactor;
695                                 BigDecimal JavaDoc price = (BigDecimal JavaDoc)createdPrice.values("price").get(0);
696                                 price = price == null ? new BigDecimal JavaDoc(0) : price;
697                                 price =
698                                     new BigDecimal JavaDoc(
699                                         price.multiply(priceMultiplier).multiply(roundingFactor).add(
700                                             new BigDecimal JavaDoc(0.5)
701                                         ).toBigInteger()
702                                     ).divide(
703                                         roundingFactor, price.scale(), BigDecimal.ROUND_FLOOR
704                                     ).add(
705                                         priceOffset
706                                     );
707                                 createdPrice.clearValues("price").add(price);
708                             }
709                         }
710                     }
711                     createdPrice.clearValues("priceLevel").add(
712                         priceLevel.path()
713                     );
714                     this.delegation.addCreateRequest(
715                         createdPrice
716                     );
717                 }
718             }
719             numberProcessed++;
720         }
721         return numberProcessed;
722     }
723     
724     //-------------------------------------------------------------------------
725
public int clearAssignedPrices(
726         ServiceHeader header,
727         DataproviderObject_1_0 priceLevel,
728         DataproviderObject_1_0 params
729     ) throws ServiceException {
730         if(
731             ((priceLevel.values("isFinal").size() > 0) &&
732             ((Boolean JavaDoc)priceLevel.values("isFinal").get(0)).booleanValue())
733         ) {
734             throw new ServiceException(
735                 OpenCrxException.DOMAIN,
736                 OpenCrxException.PRODUCT_OPERATION_NOT_ALLOWED_FOR_FINAL_PRICE_LEVEL,
737                 new BasicException.Parameter[]{
738                     new BasicException.Parameter("param0", priceLevel.path())
739                 },
740                 "Operation is not allowed for final price level."
741             );
742         }
743         if(this.isBasedOnPriceLevel(priceLevel.path())) {
744             throw new ServiceException(
745                 OpenCrxException.DOMAIN,
746                 OpenCrxException.PRODUCT_OPERATION_NOT_ALLOWED_FOR_FINAL_PRICE_LEVEL,
747                 new BasicException.Parameter[]{
748                     new BasicException.Parameter("param0", priceLevel.path())
749                 },
750                 "Operation is not allowed for final price level."
751             );
752         }
753         List JavaDoc priceListEntries = this.getAssignedPriceListEntries(
754             priceLevel
755         );
756         short processingMode = params.values("processingMode").size() > 0
757             ? ((Short JavaDoc)params.values("processingMode").get(0)).shortValue()
758             : 0;
759         // Collect identities of prices
760
// * to be removed or
761
// * unlinked (remove reference to price level) from price level
762
List JavaDoc priceIdentitiesToBeRemoved = new ArrayList JavaDoc();
763         List JavaDoc priceIdentitiesToBeUnlinked = new ArrayList JavaDoc();
764         int numberProcessed = 0;
765         for(
766             Iterator JavaDoc i = priceListEntries.iterator();
767             i.hasNext();
768         ) {
769             DataproviderObject_1_0 priceListEntry = (DataproviderObject_1_0)i.next();
770             if(
771                 (processingMode == PROCESSING_MODE_PROCESS) &&
772                 (priceListEntry.values("basePrice").size() > 0)
773             ) {
774                 if(priceListEntry.values("priceList").size() > 1) {
775                     priceIdentitiesToBeUnlinked.add(
776                         priceListEntry.values("basePrice").get(0)
777                     );
778                 }
779                 else {
780                     priceIdentitiesToBeRemoved.add(
781                         priceListEntry.values("basePrice").get(0)
782                     );
783                 }
784             }
785             numberProcessed++;
786         }
787         // Remove prices
788
for(
789             Iterator JavaDoc i = priceIdentitiesToBeRemoved.iterator();
790             i.hasNext();
791         ) {
792             this.plugin.removeObject((Path)i.next());
793         }
794         // Unlink prices
795
for(
796             Iterator JavaDoc i = priceIdentitiesToBeUnlinked.iterator();
797             i.hasNext();
798         ) {
799             DataproviderObject price = this.plugin.retrieveObjectForModification(
800                 (Path)i.next()
801             );
802             price.values("priceList").remove(
803                 priceLevel.path()
804             );
805         }
806         return numberProcessed;
807     }
808     
809     //-------------------------------------------------------------------------
810
public int createInitialPrices(
811         ServiceHeader header,
812         DataproviderObject_1_0 priceLevel,
813         DataproviderObject_1_0 params
814     ) throws ServiceException {
815         // Price level must not be final
816
if(
817             ((priceLevel.values("isFinal").size() > 0) &&
818             ((Boolean JavaDoc)priceLevel.values("isFinal").get(0)).booleanValue())
819         ) {
820             throw new ServiceException(
821                 OpenCrxException.DOMAIN,
822                 OpenCrxException.PRODUCT_OPERATION_NOT_ALLOWED_FOR_FINAL_PRICE_LEVEL,
823                 new BasicException.Parameter[]{
824                     new BasicException.Parameter("param0", priceLevel.path())
825                 },
826                 "Operation is not allowed for final price level."
827             );
828         }
829         // Price level must have price uom and currency
830
if(
831             (priceLevel.values("priceCurrency").size() == 0)
832         ) {
833             throw new ServiceException(
834                 OpenCrxException.DOMAIN,
835                 OpenCrxException.PRODUCT_PRICE_LEVEL_MUST_HAVE_CURRENCY,
836                 new BasicException.Parameter[]{
837                     new BasicException.Parameter("param0", priceLevel.path())
838                 },
839                 "Price level must have price uom and price currency."
840             );
841         }
842         short processingMode = params.values("processingMode").size() > 0
843             ? ((Short JavaDoc)params.values("processingMode").get(0)).shortValue()
844             : 0;
845             
846         // Get all products matching the product filter
847
List JavaDoc productFilter = new ArrayList JavaDoc();
848         productFilter.addAll(
849             Arrays.asList(
850                 this.getProductFilterProperties(
851                     priceLevel.path()
852                 )
853             )
854         );
855         List JavaDoc allProducts = this.delegation.addFindRequest(
856             priceLevel.path().getPrefix(5).getChild("allProduct"),
857             (FilterProperty[])productFilter.toArray(new FilterProperty[productFilter.size()]),
858             AttributeSelectors.ALL_ATTRIBUTES,
859             0,
860             Integer.MAX_VALUE,
861             Directions.ASCENDING
862         );
863         int numberProcessed = 0;
864         for(
865             Iterator JavaDoc i = allProducts.iterator();
866             i.hasNext();
867         ) {
868             DataproviderObject_1_0 product = (DataproviderObject_1_0)i.next();
869             Path productIdentity = new Path((String JavaDoc)product.values(SystemAttributes.OBJECT_IDENTITY).get(0));
870             List JavaDoc basePrices = this.findPrices(
871                 priceLevel,
872                 false,
873                 productIdentity
874             );
875             if(basePrices.size() == 0) {
876                 DataproviderObject basePrice = new DataproviderObject(
877                     productIdentity.getDescendant(new String JavaDoc[]{"basePrice", this.plugin.getUidAsString()})
878                 );
879                 basePrice.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:product1:ProductBasePrice");
880                 basePrice.values("priceLevel").add(
881                     priceLevel.path()
882                 );
883                 basePrice.values("usage").addAll(
884                     priceLevel.values("priceUsage")
885                 );
886                 basePrice.values("price").add(
887                     new BigDecimal JavaDoc(0)
888                 );
889                 basePrice.values("priceCurrency").addAll(
890                     priceLevel.values("priceCurrency")
891                 );
892                 basePrice.values("discount").add(
893                     new BigDecimal JavaDoc(0)
894                 );
895                 basePrice.values("discountIsPercentage").add(
896                     Boolean.FALSE
897                 );
898                 basePrice.values("uom").addAll(
899                     params.values("priceUom")
900                 );
901                 if(processingMode == PROCESSING_MODE_PROCESS) {
902                     this.delegation.addCreateRequest(
903                         basePrice
904                     );
905                 }
906                 numberProcessed++;
907             }
908         }
909         return numberProcessed;
910     }
911     
912     //-------------------------------------------------------------------------
913
public void getPriceLevel(
914         ServiceHeader header,
915         DataproviderObject_1_0 pricingRule,
916         DataproviderObject_1_0 params,
917         DataproviderObject priceLevelResult
918     ) throws ServiceException {
919         try {
920             org.opencrx.kernel.product1.cci.GetPriceLevelResult res =
921                 this.getPriceLevel(
922                     (org.opencrx.kernel.product1.cci.PricingRule)this.rootPkg.refObject(pricingRule.path().toXri()),
923                     params.values("contract").size() == 0
924                         ? null
925                         : (org.opencrx.kernel.contract1.cci.AbstractContract)this.rootPkg.refObject(((Path)params.values("contract").get(0)).toXri()),
926                     params.values("product").size() == 0
927                         ? null
928                         : (org.opencrx.kernel.product1.cci.AbstractProduct)this.rootPkg.refObject(((Path)params.values("product").get(0)).toXri()),
929                     params.values("priceUom").size() == 0
930                         ? null
931                         : (org.opencrx.kernel.uom1.cci.Uom)this.rootPkg.refObject(((Path)params.values("priceUom").get(0)).toXri()),
932                     (BigDecimal JavaDoc)params.values("quantity").get(0),
933                     params.values("pricingDate").size() == 0
934                         ? null
935                         : org.openmdx.base.text.format.DateFormat.getInstance().parse((String JavaDoc)params.values("pricingDate").get(0))
936                 );
937             priceLevelResult.values("statusCode").add(
938                 new Short JavaDoc(STATUS_CODE_OK)
939             );
940             if(res != null) {
941                 if(res.refDelegate().objGetValue("priceLevel") != null) {
942                     priceLevelResult.values("priceLevel").add(
943                         res.refDelegate().objGetValue("priceLevel")
944                     );
945                 }
946                 if(res.getDiscount() != null) {
947                     priceLevelResult.values("discount").add(
948                         res.getDiscount()
949                     );
950                 }
951                 if(res.isDiscountIsPercentage() != null) {
952                     priceLevelResult.values("discountIsPercentage").add(
953                         res.isDiscountIsPercentage()
954                     );
955                 }
956             }
957         }
958         catch(ParseException JavaDoc e) {
959             priceLevelResult.values("statusCode").add(
960                 new Short JavaDoc(STATUS_CODE_ERROR)
961             );
962             priceLevelResult.values("statusMessage").add(
963                 "Can not parse pricingDate"
964             );
965         }
966     }
967
968     //-------------------------------------------------------------------------
969
public org.opencrx.kernel.product1.cci.GetPriceLevelResult getPriceLevel(
970         org.opencrx.kernel.product1.cci.PricingRule pricingRule,
971         org.opencrx.kernel.contract1.cci.AbstractContract contract,
972         org.opencrx.kernel.product1.cci.AbstractProduct product,
973         org.opencrx.kernel.uom1.cci.Uom priceUom,
974         BigDecimal JavaDoc quantity,
975         Date JavaDoc pricingDate
976     ) throws ServiceException {
977         String JavaDoc script = (pricingRule.getGetPriceLevelScript() == null) || (pricingRule.getGetPriceLevelScript().length() == 0)
978             ? DEFAULT_GET_PRICE_LEVEL_SCRIPT
979             : pricingRule.getGetPriceLevelScript();
980         org.opencrx.kernel.product1.cci.product1Package productPkg =
981             (org.opencrx.kernel.product1.cci.product1Package)rootPkg.refPackage(
982                 org.opencrx.kernel.product1.cci.product1Package.class.getName()
983             );
984         try {
985             Class JavaDoc c = new ClassBodyEvaluator(script).evaluate();
986             Method JavaDoc m = c.getMethod(
987                 "getPriceLevel",
988                 new Class JavaDoc[] {
989                     org.openmdx.base.accessor.jmi.cci.RefPackage_1_0.class,
990                     org.opencrx.kernel.product1.cci.PricingRule.class,
991                     org.opencrx.kernel.contract1.cci.AbstractContract.class,
992                     org.opencrx.kernel.product1.cci.AbstractProduct.class,
993                     org.opencrx.kernel.uom1.cci.Uom.class,
994                     java.math.BigDecimal JavaDoc.class,
995                     java.util.Date JavaDoc.class
996                 }
997             );
998             return (org.opencrx.kernel.product1.cci.GetPriceLevelResult)m.invoke(
999                 null,
1000                new Object JavaDoc[] {
1001                    this.rootPkg,
1002                    pricingRule,
1003                    contract,
1004                    product,
1005                    priceUom,
1006                    quantity,
1007                    pricingDate
1008                }
1009            );
1010        }
1011        catch(CompileException e) {
1012            return productPkg.createGetPriceLevelResult(
1013                null, null, null,
1014                STATUS_CODE_ERROR,
1015                "Can not compile getPriceLevelScript:\n" +
1016                e.getMessage()
1017            );
1018        }
1019        catch(Parser.ParseException e) {
1020            return productPkg.createGetPriceLevelResult(
1021                null, null, null,
1022                STATUS_CODE_ERROR,
1023                "Can not parse getPriceLevelScript:\n" +
1024                e.getMessage()
1025            );
1026        }
1027        catch(Scanner.ScanException e) {
1028            return productPkg.createGetPriceLevelResult(
1029                null, null, null,
1030                STATUS_CODE_ERROR,
1031                "Can not scan getPriceLevelScript:\n" +
1032                e.getMessage()
1033            );
1034        }
1035        catch(NoSuchMethodException JavaDoc e) {
1036            return productPkg.createGetPriceLevelResult(
1037                null, null, null,
1038                STATUS_CODE_ERROR,
1039                "getPriceLevelScript does not define a method with the following signature:\n" +
1040                DEFAULT_GET_PRICE_LEVEL_SCRIPT
1041            );
1042        }
1043        catch(InvocationTargetException JavaDoc e) {
1044            return productPkg.createGetPriceLevelResult(
1045                null, null, null,
1046                STATUS_CODE_ERROR,
1047                "Can not invoke getPriceLevel():\n" +
1048                e.getTargetException().getMessage()
1049            );
1050        }
1051        catch(IllegalAccessException JavaDoc e) {
1052            return productPkg.createGetPriceLevelResult(
1053                null, null, null,
1054                STATUS_CODE_ERROR,
1055                "Illegal access when invoking getPriceLevel():\n" +
1056                e.getMessage()
1057            );
1058        }
1059    }
1060
1061    //-------------------------------------------------------------------------
1062
private boolean isBasedOnPriceLevel(
1063        Path priceLevelIdentity
1064    ) throws ServiceException {
1065        List JavaDoc dependingPriceLevels = this.delegation.addFindRequest(
1066            priceLevelIdentity.getParent(),
1067            new FilterProperty[]{
1068                new FilterProperty(
1069                    Quantors.THERE_EXISTS,
1070                    "basedOn",
1071                    FilterOperators.IS_IN,
1072                    new Object JavaDoc[]{priceLevelIdentity}
1073                )
1074            }
1075        );
1076        return dependingPriceLevels.size() > 0;
1077    }
1078    
1079    //-------------------------------------------------------------------------
1080
public void removePriceLevel(
1081        ServiceHeader header,
1082        Path priceLevelIdentity
1083    ) throws ServiceException {
1084        if(this.isBasedOnPriceLevel(priceLevelIdentity)) {
1085            throw new ServiceException(
1086                OpenCrxException.DOMAIN,
1087                OpenCrxException.PRODUCT_OPERATION_NOT_ALLOWED_FOR_BASEDON_PRICE_LEVEL,
1088                new BasicException.Parameter[]{
1089                    new BasicException.Parameter("param0", priceLevelIdentity)
1090                },
1091                "Can not delete price level. Other price levels are based on this price level."
1092            );
1093        }
1094        // Check for prices which are assigned to price level
1095
List JavaDoc priceListEntries = this.delegation.addFindRequest(
1096            priceLevelIdentity.getPrefix(5).getChild("priceListEntry"),
1097            new FilterProperty[]{
1098                new FilterProperty(
1099                    Quantors.THERE_EXISTS,
1100                    "priceLevel",
1101                    FilterOperators.IS_IN,
1102                    new Object JavaDoc[]{priceLevelIdentity}
1103                    
1104                )
1105            }
1106        );
1107        if(priceListEntries.size() > 0) {
1108            throw new ServiceException(
1109                OpenCrxException.DOMAIN,
1110                OpenCrxException.PRODUCT_OPERATION_NOT_ALLOWED_FOR_PRICE_LEVEL_HAVING_PRICES,
1111                new BasicException.Parameter[]{
1112                    new BasicException.Parameter("param0", priceLevelIdentity)
1113                },
1114                "Can not delete price level. Price level has assigned prices."
1115            );
1116        }
1117        DataproviderObject_1_0 priceLevel = this.plugin.retrieveObjectFromDelegation(priceLevelIdentity);
1118        if(
1119            (priceLevel.values("isFinal").size() > 0) &&
1120            ((Boolean JavaDoc)priceLevel.values("isFinal").get(0)).booleanValue()
1121        ) {
1122            throw new ServiceException(
1123                OpenCrxException.DOMAIN,
1124                OpenCrxException.PRODUCT_OPERATION_NOT_ALLOWED_FOR_FINAL_PRICE_LEVEL,
1125                new BasicException.Parameter[]{
1126                    new BasicException.Parameter("param0", priceLevel.path())
1127                },
1128                "Can not delete final price level."
1129            );
1130        }
1131        this.plugin.removeObject(priceLevel.path());
1132    }
1133    
1134    //-------------------------------------------------------------------------
1135
// Members
1136
//-------------------------------------------------------------------------
1137
private final static int BATCHING_MODE_SIZE = 1000;
1138    
1139    private static final short PROCESSING_MODE_NA = 0;
1140    private static final short PROCESSING_MODE_TEST = 1;
1141    private static final short PROCESSING_MODE_PROCESS = 2;
1142    
1143    private final static short STATUS_CODE_OK = 0;
1144    private final static short STATUS_CODE_ERROR = 1;
1145    
1146    private static final String JavaDoc DEFAULT_GET_PRICE_LEVEL_SCRIPT =
1147        "public static org.opencrx.kernel.product1.cci.GetPriceLevelResult getPriceLevel(\n" +
1148            "org.openmdx.base.accessor.jmi.cci.RefPackage_1_0 rootPkg,\n" +
1149            "org.opencrx.kernel.product1.cci.PricingRule pricingRule,\n" +
1150            "org.opencrx.kernel.contract1.cci.AbstractContract contract,\n" +
1151            "org.opencrx.kernel.product1.cci.AbstractProduct product,\n" +
1152            "org.opencrx.kernel.uom1.cci.Uom priceUom,\n" +
1153            "java.math.BigDecimal quantity,\n" +
1154            "java.util.Date pricingDate\n" +
1155        ") {\n" +
1156            "org.opencrx.kernel.product1.cci.product1Package productPkg =\n" +
1157                "(org.opencrx.kernel.product1.cci.product1Package)rootPkg.refPackage(\n" +
1158                    "org.opencrx.kernel.product1.cci.product1Package.class.getName()\n" +
1159                ");\n" +
1160            "org.opencrx.kernel.product1.cci.GetPriceLevelResult result = productPkg.createGetPriceLevelResult(\n" +
1161                "null,\n" +
1162                "null,\n" +
1163                "null,\n" +
1164                "(short)0,\n" +
1165                "null\n" +
1166            ");\n" +
1167            "return result;\n" +
1168        "}";
1169    
1170    private final Model_1_0 model;
1171    private final OpenCrxKernel_1 plugin;
1172    private final RequestCollection delegation;
1173    private final RefPackage_1_0 rootPkg;
1174    
1175}
1176
1177//--- End of File -----------------------------------------------------------
1178
Popular Tags