if (!JbpmConstantsRecurringOffer.Vendor.NODE_NAME_RECURRENCE_STARTED.equals(nodeName)) {
throw new IllegalStateException("The recurrence for RecurringOffer " + JDOHelper.getObjectId(recurringOffer) + " is not started, it is in the state '" + nodeName + "'.");
}
logger.debug("Starting creation of RecurredOffer (with new Order) for RecurringOffer: " + JDOHelper.getObjectId(recurringOffer));
PersistenceManager pm = getPersistenceManager();
Trader trader = Trader.getTrader(pm);
Order order = trader.createOrder(recurringOffer.getVendor(),
recurringOffer.getCustomer(), null, recurringOffer.getCurrency());
logger.debug("Created Order: " + JDOHelper.getObjectId(order));
User user = SecurityReflector.getUserDescriptor().getUser(pm);
String offerIDPrefix = recurringOffer.getOfferIDPrefix();
Collection<Segment> recurringSegments = new HashSet<Segment>();
for (Article article : recurringOffer.getArticles()) {
recurringSegments.add(article.getSegment());
}
// create the new segment for the order
for (Segment segment : recurringSegments) {
trader.createSegment(order, segment.getSegmentType());
}
RecurredOffer recurredOffer = createRecurredOffer(recurringOffer,user, order, offerIDPrefix);
logger.debug("Created RecurredOffer: " + JDOHelper.getObjectId(recurredOffer));
// Loop over all articles in the given offer and group
// them by SegmentType and ProductType-class
Map<SegmentType, Map<Class<? extends ProductType>, Set<Article>>> segmentTypes2PTClass2Articles = new HashMap<SegmentType, Map<Class<? extends ProductType>, Set<Article>>>();
Set<Article> articles = new HashSet<Article>();
for (Article recurringArticle : recurringOffer.getArticles()) {
SegmentType segmentType = recurringArticle.getSegment().getSegmentType();
Map<Class<? extends ProductType>, Set<Article>> ptClass2Articles = segmentTypes2PTClass2Articles.get(segmentType);
if (ptClass2Articles == null) {
ptClass2Articles = new HashMap<Class<? extends ProductType>, Set<Article>>();
segmentTypes2PTClass2Articles.put(segmentType, ptClass2Articles);
}
Class<? extends ProductType> productTypeClass = recurringArticle.getProductType().getClass();
articles = ptClass2Articles.get(productTypeClass);
if (articles == null) {
articles = new HashSet<Article>();
ptClass2Articles.put(productTypeClass, articles);
}
articles.add(recurringArticle);
}
if (logger.isDebugEnabled()) {
logger.debug("Grouped articles in RecurringOffer:");
for (Map.Entry<SegmentType, Map<Class<? extends ProductType>, Set<Article>>> segmentTypeEntry : segmentTypes2PTClass2Articles.entrySet()) {
logger.debug(" SegmentType: " + JDOHelper.getObjectId(segmentTypeEntry.getKey()));
for (Map.Entry<Class<? extends ProductType>, Set<Article>> productTypeEntry : segmentTypeEntry.getValue().entrySet()) {
logger.debug(" ProductType class: " + productTypeEntry.getKey());
for (Article article : productTypeEntry.getValue()) {
logger.debug(" Article: " + JDOHelper.getObjectId(article));
}
}
}
}
// loop over the segments added to the order
for (Segment segment : order.getSegments()) {
logger.debug("Creating articles for RecurredOffer for SegmentType " + JDOHelper.getObjectId(segment.getSegmentType()));
Map<Class<? extends ProductType>, Set<Article>> collected = segmentTypes2PTClass2Articles.get(segment.getSegmentType());
if (collected != null) { // it is possible that there are segments with no articles in the RecurringOffer
// add each segment to the RecurredOffer
recurredOffer.addSegment(segment);
for (Iterator< Class<? extends ProductType>> it = collected.keySet().iterator(); it.hasNext();)
{
// now for each ProductType class find the handler and let him create the articles
Class<? extends ProductType> pt = it.next();
logger.debug(" Creating articles for RecurredOffer for ProductType class " + pt);
articles = collected.get(pt);
RecurringTradeProductTypeActionHandler handler = RecurringTradeProductTypeActionHandler.getRecurringTradeProductTypeActionHandler(pm, pt);
if (handler == null)
throw new IllegalStateException("Could not find a " + RecurringTradeProductTypeActionHandler.class.getName() +
" for the ProductType class " + pt);
logger.debug(" Found handler " + handler.getClass().getName() + " ProductType class " + pt);
Map<Article, Article> recurredArticles = handler.createArticles(recurredOffer, articles, segment);
if(recurredArticles.size() != articles.size())
throw new IllegalStateException(
"RecurringTradeProductTypeActionHandler " + handler.getClass().getName() +
" created " + recurredArticles.size() + " recurred articles for " + articles.size() +
" template/recurring articles");
for (Map.Entry<Article, Article> articleEntry : recurredArticles.entrySet()) {
// Compare Prices to check if they the Differ
Price recurringPrice = articleEntry.getValue().getPrice();
Price recurredPrice = articleEntry.getKey().getPrice();
// if amount or currency differs
if (recurredPrice.getAmount() != recurringPrice.getAmount() || !recurredPrice.getCurrency().equals(recurringPrice.getCurrency()))
priceDiffer = true;
if (logger.isDebugEnabled()) {
if (!articleEntry.getValue().isAllocated()) {
logger.debug(" An Article was created which was NOT allocated: " + JDOHelper.getObjectId(articleEntry.getValue()));
} else {
logger.debug(" An allocated Article was created: " + JDOHelper.getObjectId(articleEntry.getValue()));
}
logger.debug(" Finished creatingArticles");
}
}
}
}
}
// TODO: Check/Compare article prices from RecurringOffer and crated RecurredOffer
/* Depending on the configuration of the RecurringOffer the following strageties should be supported:
* * Always use offered prices (Meaning that the process will enforce the
* old prices for the newly created RecurredOffer)
* * Use offered prices but don't finalize (Meaning that the old prices will
* be used, but the new offer will not be finalized, it would be best if this
* could somehow notify the user then, but this for later)
* * Use current prices (Meaning that the process will always take the
* current prices for the new offers, this is what currently happens)
* * Use current prices but don't finalize (Meaning that the new prices will
* be used, but the new offer will not be finalized)
* How to enforce old prices is not absolutely clear to me now, but I know
* that it's possible somehow
*
* Alex
*/
// finished creating articles
if(!priceDiffer)
{
// For now, as long as the different strategies are not present, we directly accept the offer.
trader.acceptOfferImplicitely(recurredOffer);
if(recurringOffer.getRecurringOfferConfiguration().isCreateInvoice()) {
// If the configuration says so, automatically create an invoice
logger.debug("Creating invoice for new RecurredOffer");