/src/classes/com/sapienter/jbilling/server/item/tasks/RulesItemManager.java
Java | 299 lines | 214 code | 41 blank | 44 comment | 22 complexity | adc50c2125e0166c08c70cdf92e1fac4 MD5 | raw file
- /*
- jBilling - The Enterprise Open Source Billing System
- Copyright (C) 2003-2009 Enterprise jBilling Software Ltd. and Emiliano Conde
- This file is part of jbilling.
- jbilling is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- jbilling is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with jbilling. If not, see <http://www.gnu.org/licenses/>.
- */
- package com.sapienter.jbilling.server.item.tasks;
- import java.math.BigDecimal;
- import java.util.Collection;
- import java.util.Date;
- import org.apache.log4j.Logger;
- import org.drools.KnowledgeBase;
- import org.drools.runtime.rule.FactHandle;
- import com.sapienter.jbilling.common.Constants;
- import com.sapienter.jbilling.server.item.ItemBL;
- import com.sapienter.jbilling.server.item.PricingField;
- import com.sapienter.jbilling.server.item.db.ItemDTO;
- import com.sapienter.jbilling.server.mediation.Record;
- import com.sapienter.jbilling.server.order.OrderBL;
- import com.sapienter.jbilling.server.order.db.OrderDAS;
- import com.sapienter.jbilling.server.order.db.OrderDTO;
- import com.sapienter.jbilling.server.order.db.OrderLineDAS;
- import com.sapienter.jbilling.server.order.db.OrderLineDTO;
- import com.sapienter.jbilling.server.order.db.OrderStatusDAS;
- import com.sapienter.jbilling.server.pluggableTask.TaskException;
- import com.sapienter.jbilling.server.user.ContactBL;
- import com.sapienter.jbilling.server.user.ContactDTOEx;
- import com.sapienter.jbilling.server.user.UserDTOEx;
- import com.sapienter.jbilling.server.user.contact.db.ContactFieldDTO;
- import com.sapienter.jbilling.server.util.DTOFactory;
- import com.sapienter.jbilling.server.util.db.CurrencyDAS;
- import java.util.ArrayList;
- import java.util.List;
- public class RulesItemManager extends BasicItemManager {
- private static final Logger LOG = Logger.getLogger(RulesItemManager.class);
- protected OrderManager helperOrder = null;
- private List<Record> records;
- public void addItem(Integer itemID, BigDecimal quantity, Integer language,
- Integer userId, Integer entityId, Integer currencyId,
- OrderDTO order, List<Record> records) throws TaskException {
- super.addItem(itemID, quantity, language, userId, entityId, currencyId, order, records);
- this.records = records;
- helperOrder = new OrderManager(order, language, userId, entityId, currencyId);
- processRules(order);
- }
- protected void processRules(OrderDTO newOrder) throws TaskException {
- // now we have the line with good defaults, the order and the item
- // These have to be visible to the rules
- KnowledgeBase knowledgeBase;
- try {
- knowledgeBase = readKnowledgeBase();
- } catch (Exception e) {
- throw new TaskException(e);
- }
- session = knowledgeBase.newStatefulKnowledgeSession();
- List<Object> rulesMemoryContext = new ArrayList<Object>();
- rulesMemoryContext.add(helperOrder);
- // add OrderDTO to rules memory context
- newOrder.setCurrency(new CurrencyDAS().find(newOrder.getCurrency().getId()));
- if (newOrder.getCreateDate() == null) {
- newOrder.setCreateDate(new Date());
- }
- rulesMemoryContext.add(newOrder);
- for (OrderLineDTO line : newOrder.getLines()) {
- if (line.getItem() != null) {
- ItemBL item = new ItemBL(line.getItemId());
- rulesMemoryContext.add(item.getDTO(helperOrder.getLanguage(), helperOrder.getUserId(),
- helperOrder.getEntityId(), helperOrder.getCurrencyId()));
- }
- rulesMemoryContext.add(line);
- }
- if (newOrder.getPricingFields() != null && newOrder.getPricingFields().size() > 0) {
- for (PricingField pf : newOrder.getPricingFields()) {
- rulesMemoryContext.add(pf);
- }
- }
- try {
- Integer userId = newOrder.getBaseUserByUserId().getId();
- UserDTOEx user = DTOFactory.getUserDTOEx(userId);
- rulesMemoryContext.add(user);
- ContactBL contact = new ContactBL();
- contact.set(userId);
- ContactDTOEx contactDTO = contact.getDTO();
- rulesMemoryContext.add(contactDTO);
- for (ContactFieldDTO field : (Collection<ContactFieldDTO>) contactDTO.getFieldsTable().values()) {
- rulesMemoryContext.add(field);
- }
- // Add the subscriptions
- OrderBL order = new OrderBL();
- for (OrderDTO myOrder : order.getActiveRecurringByUser(userId)) {
- for (OrderLineDTO myLine : myOrder.getLines()) {
- rulesMemoryContext.add(new Subscription(myLine));
- }
- }
- } catch (Exception e) {
- throw new TaskException(e);
- }
- session.setGlobal("order", helperOrder);
- // then execute the rules
- executeStatefulRules(session, rulesMemoryContext);
- }
- public class OrderManager {
- private OrderDTO order = null;
- private Integer language = null;
- private Integer userId = null;
- private Integer entityId = null;
- private Integer currencyId = null;
- public OrderManager(OrderDTO order, Integer language,
- Integer userId, Integer entityId, Integer currencyId) {
- this.order = order;
- this.language = language;
- this.userId = userId;
- this.entityId = entityId;
- this.currencyId = currencyId;
- }
- public OrderDTO getOrder() {
- return order;
- }
- public void setOrder(OrderDTO order) {
- this.order = order;
- }
- public OrderLineDTO addItem(Integer itemID, Integer quantity)
- throws TaskException {
- return addItem(itemID, new BigDecimal(quantity));
- }
- public OrderLineDTO addItem(Integer itemID, BigDecimal quantity)
- throws TaskException {
- LOG.debug("Adding item " + itemID + " q: " + quantity);
- BasicItemManager helper = new BasicItemManager();
- OrderLineDTO oldLine = order.getLine(itemID);
- FactHandle h = null;
- if (oldLine != null) {
- h = handlers.get(oldLine);
- }
- helper.addItem(itemID, quantity, language, userId, entityId, currencyId, order, records);
- OrderLineDTO retValue = helper.getLatestLine();
- if (h != null) {
- LOG.debug("updating");
- session.update(h, retValue);
- } else {
- LOG.debug("inserting");
- handlers.put(retValue, session.insert(retValue));
- }
- LOG.debug("Now order line is " + retValue + " hash: " + retValue.hashCode());
- return retValue;
- }
- public OrderLineDTO addItem(Integer itemId) throws TaskException {
- return addItem(itemId, 1);
- }
- public void removeItem(Integer itemId) {
- removeObject(order.getLine(itemId));
- order.removeLine(itemId);
- }
- /**
- * Adds or updates an order line. It will calculate the amount to add based on the
- * price of the itemBase, using the price as a percentage of the itemId
- * @param itemId
- * @param itemBase
- * @return
- * @throws TaskException
- */
- public OrderLineDTO percentageIncrease(Integer itemId, Integer itemBase)
- throws TaskException {
- OrderLineDTO updateLine = order.getLine(itemId);
- if (updateLine == null) {
- // no luck, create a new one
- updateLine = addItem(itemId);
- updateLine.setAmount(BigDecimal.ZERO); // starts from 0
- updateLine.setTotalReadOnly(true);
- }
- // now add the amount based on the itemBase
- ItemBL item = new ItemBL(itemBase);
- ItemDTO itemDto = item.getDTO(language, userId, entityId, currencyId);
- BigDecimal percentage = updateLine.getItem().getPercentage();
- BigDecimal base = itemDto.getPrice();
- BigDecimal result = base.divide(new BigDecimal("100"), Constants.BIGDECIMAL_SCALE, Constants.BIGDECIMAL_ROUND)
- .multiply(percentage).add(updateLine.getAmount());
- updateLine.setAmount(result);
- return updateLine;
- }
- /**
- * Adds or updates an order line. Calculates a percentage item order
- * line amount based on the amount of another order line. This is added
- * to the existing percentage order line's amount.
- */
- public OrderLineDTO percentageOnOrderLine(Integer percentageItemId,
- OrderLineDTO line) throws TaskException {
- // try to get percentage item order line
- OrderLineDTO percentageLine = order.getLine(percentageItemId);
- if (percentageLine == null) {
- // add percentage item
- percentageLine = addItem(percentageItemId);
- percentageLine.setAmount(BigDecimal.ZERO);
- percentageLine.setTotalReadOnly(true);
- }
- // now add the percentage amount based on the order line item amount
- BigDecimal percentage = percentageLine.getItem().getPercentage();
- BigDecimal base = line.getPrice().multiply(line.getQuantity());
- BigDecimal result = base.divide(new BigDecimal("100"), Constants.BIGDECIMAL_SCALE,
- Constants.BIGDECIMAL_ROUND).multiply(percentage).add(percentageLine.getAmount());
- percentageLine.setAmount(result);
- return percentageLine;
- }
- public OrderDTO createOrder(Integer itemId, Double quantity) throws TaskException {
- BigDecimal quant = new BigDecimal(quantity).setScale(Constants.BIGDECIMAL_SCALE, Constants.BIGDECIMAL_ROUND);
- return createOrder(itemId, quant);
- }
- public OrderDTO createOrder(Integer itemId, BigDecimal quantity)
- throws TaskException {
- // copy the current order
- OrderDTO newOrder = new OrderDTO(order);
- newOrder.setId(0);
- newOrder.setVersionNum(null);
- // the period needs to be in the session
- newOrder.setOrderPeriodId(order.getOrderPeriod().getId());
- // the status should be active
- newOrder.setOrderStatus(new OrderStatusDAS().find(Constants.ORDER_STATUS_ACTIVE));
- // but without the lines
- newOrder.getLines().clear();
- // but do get the new line in
- OrderManager helper = new OrderManager(newOrder, language, userId, entityId, currencyId);
- OrderLineDTO newLine = helper.addItem(itemId, quantity);
- newLine.setPurchaseOrder(newOrder);
- newLine.setDefaults();
-
- return new OrderDAS().save(newOrder);
- }
- public void removeOrder(Integer itemId) {
- List<OrderLineDTO> list = new OrderLineDAS().findByUserItem(
- order.getBaseUserByUserId().getId(), itemId);
- for (OrderLineDTO line : list) {
- LOG.debug("Deleting order " + line.getPurchaseOrder().getId());
- // who is the executor? we'll use the owner.. she is cancelling
- new OrderBL(line.getPurchaseOrder()).delete(order.getBaseUserByUserId().getId());
- }
- }
- public Integer getCurrencyId() {
- return currencyId;
- }
- public Integer getEntityId() {
- return entityId;
- }
- public Integer getLanguage() {
- return language;
- }
- public Integer getUserId() {
- return userId;
- }
- }
- }