PageRenderTime 39ms CodeModel.GetById 7ms RepoModel.GetById 0ms app.codeStats 0ms

/src/classes/com/sapienter/jbilling/server/item/tasks/RulesItemManager.java

https://github.com/bibulous/SkyrackJbill2.2
Java | 299 lines | 214 code | 41 blank | 44 comment | 22 complexity | adc50c2125e0166c08c70cdf92e1fac4 MD5 | raw file
  1. /*
  2. jBilling - The Enterprise Open Source Billing System
  3. Copyright (C) 2003-2009 Enterprise jBilling Software Ltd. and Emiliano Conde
  4. This file is part of jbilling.
  5. jbilling is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU Affero General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. jbilling is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU Affero General Public License for more details.
  13. You should have received a copy of the GNU Affero General Public License
  14. along with jbilling. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. package com.sapienter.jbilling.server.item.tasks;
  17. import java.math.BigDecimal;
  18. import java.util.Collection;
  19. import java.util.Date;
  20. import org.apache.log4j.Logger;
  21. import org.drools.KnowledgeBase;
  22. import org.drools.runtime.rule.FactHandle;
  23. import com.sapienter.jbilling.common.Constants;
  24. import com.sapienter.jbilling.server.item.ItemBL;
  25. import com.sapienter.jbilling.server.item.PricingField;
  26. import com.sapienter.jbilling.server.item.db.ItemDTO;
  27. import com.sapienter.jbilling.server.mediation.Record;
  28. import com.sapienter.jbilling.server.order.OrderBL;
  29. import com.sapienter.jbilling.server.order.db.OrderDAS;
  30. import com.sapienter.jbilling.server.order.db.OrderDTO;
  31. import com.sapienter.jbilling.server.order.db.OrderLineDAS;
  32. import com.sapienter.jbilling.server.order.db.OrderLineDTO;
  33. import com.sapienter.jbilling.server.order.db.OrderStatusDAS;
  34. import com.sapienter.jbilling.server.pluggableTask.TaskException;
  35. import com.sapienter.jbilling.server.user.ContactBL;
  36. import com.sapienter.jbilling.server.user.ContactDTOEx;
  37. import com.sapienter.jbilling.server.user.UserDTOEx;
  38. import com.sapienter.jbilling.server.user.contact.db.ContactFieldDTO;
  39. import com.sapienter.jbilling.server.util.DTOFactory;
  40. import com.sapienter.jbilling.server.util.db.CurrencyDAS;
  41. import java.util.ArrayList;
  42. import java.util.List;
  43. public class RulesItemManager extends BasicItemManager {
  44. private static final Logger LOG = Logger.getLogger(RulesItemManager.class);
  45. protected OrderManager helperOrder = null;
  46. private List<Record> records;
  47. public void addItem(Integer itemID, BigDecimal quantity, Integer language,
  48. Integer userId, Integer entityId, Integer currencyId,
  49. OrderDTO order, List<Record> records) throws TaskException {
  50. super.addItem(itemID, quantity, language, userId, entityId, currencyId, order, records);
  51. this.records = records;
  52. helperOrder = new OrderManager(order, language, userId, entityId, currencyId);
  53. processRules(order);
  54. }
  55. protected void processRules(OrderDTO newOrder) throws TaskException {
  56. // now we have the line with good defaults, the order and the item
  57. // These have to be visible to the rules
  58. KnowledgeBase knowledgeBase;
  59. try {
  60. knowledgeBase = readKnowledgeBase();
  61. } catch (Exception e) {
  62. throw new TaskException(e);
  63. }
  64. session = knowledgeBase.newStatefulKnowledgeSession();
  65. List<Object> rulesMemoryContext = new ArrayList<Object>();
  66. rulesMemoryContext.add(helperOrder);
  67. // add OrderDTO to rules memory context
  68. newOrder.setCurrency(new CurrencyDAS().find(newOrder.getCurrency().getId()));
  69. if (newOrder.getCreateDate() == null) {
  70. newOrder.setCreateDate(new Date());
  71. }
  72. rulesMemoryContext.add(newOrder);
  73. for (OrderLineDTO line : newOrder.getLines()) {
  74. if (line.getItem() != null) {
  75. ItemBL item = new ItemBL(line.getItemId());
  76. rulesMemoryContext.add(item.getDTO(helperOrder.getLanguage(), helperOrder.getUserId(),
  77. helperOrder.getEntityId(), helperOrder.getCurrencyId()));
  78. }
  79. rulesMemoryContext.add(line);
  80. }
  81. if (newOrder.getPricingFields() != null && newOrder.getPricingFields().size() > 0) {
  82. for (PricingField pf : newOrder.getPricingFields()) {
  83. rulesMemoryContext.add(pf);
  84. }
  85. }
  86. try {
  87. Integer userId = newOrder.getBaseUserByUserId().getId();
  88. UserDTOEx user = DTOFactory.getUserDTOEx(userId);
  89. rulesMemoryContext.add(user);
  90. ContactBL contact = new ContactBL();
  91. contact.set(userId);
  92. ContactDTOEx contactDTO = contact.getDTO();
  93. rulesMemoryContext.add(contactDTO);
  94. for (ContactFieldDTO field : (Collection<ContactFieldDTO>) contactDTO.getFieldsTable().values()) {
  95. rulesMemoryContext.add(field);
  96. }
  97. // Add the subscriptions
  98. OrderBL order = new OrderBL();
  99. for (OrderDTO myOrder : order.getActiveRecurringByUser(userId)) {
  100. for (OrderLineDTO myLine : myOrder.getLines()) {
  101. rulesMemoryContext.add(new Subscription(myLine));
  102. }
  103. }
  104. } catch (Exception e) {
  105. throw new TaskException(e);
  106. }
  107. session.setGlobal("order", helperOrder);
  108. // then execute the rules
  109. executeStatefulRules(session, rulesMemoryContext);
  110. }
  111. public class OrderManager {
  112. private OrderDTO order = null;
  113. private Integer language = null;
  114. private Integer userId = null;
  115. private Integer entityId = null;
  116. private Integer currencyId = null;
  117. public OrderManager(OrderDTO order, Integer language,
  118. Integer userId, Integer entityId, Integer currencyId) {
  119. this.order = order;
  120. this.language = language;
  121. this.userId = userId;
  122. this.entityId = entityId;
  123. this.currencyId = currencyId;
  124. }
  125. public OrderDTO getOrder() {
  126. return order;
  127. }
  128. public void setOrder(OrderDTO order) {
  129. this.order = order;
  130. }
  131. public OrderLineDTO addItem(Integer itemID, Integer quantity)
  132. throws TaskException {
  133. return addItem(itemID, new BigDecimal(quantity));
  134. }
  135. public OrderLineDTO addItem(Integer itemID, BigDecimal quantity)
  136. throws TaskException {
  137. LOG.debug("Adding item " + itemID + " q: " + quantity);
  138. BasicItemManager helper = new BasicItemManager();
  139. OrderLineDTO oldLine = order.getLine(itemID);
  140. FactHandle h = null;
  141. if (oldLine != null) {
  142. h = handlers.get(oldLine);
  143. }
  144. helper.addItem(itemID, quantity, language, userId, entityId, currencyId, order, records);
  145. OrderLineDTO retValue = helper.getLatestLine();
  146. if (h != null) {
  147. LOG.debug("updating");
  148. session.update(h, retValue);
  149. } else {
  150. LOG.debug("inserting");
  151. handlers.put(retValue, session.insert(retValue));
  152. }
  153. LOG.debug("Now order line is " + retValue + " hash: " + retValue.hashCode());
  154. return retValue;
  155. }
  156. public OrderLineDTO addItem(Integer itemId) throws TaskException {
  157. return addItem(itemId, 1);
  158. }
  159. public void removeItem(Integer itemId) {
  160. removeObject(order.getLine(itemId));
  161. order.removeLine(itemId);
  162. }
  163. /**
  164. * Adds or updates an order line. It will calculate the amount to add based on the
  165. * price of the itemBase, using the price as a percentage of the itemId
  166. * @param itemId
  167. * @param itemBase
  168. * @return
  169. * @throws TaskException
  170. */
  171. public OrderLineDTO percentageIncrease(Integer itemId, Integer itemBase)
  172. throws TaskException {
  173. OrderLineDTO updateLine = order.getLine(itemId);
  174. if (updateLine == null) {
  175. // no luck, create a new one
  176. updateLine = addItem(itemId);
  177. updateLine.setAmount(BigDecimal.ZERO); // starts from 0
  178. updateLine.setTotalReadOnly(true);
  179. }
  180. // now add the amount based on the itemBase
  181. ItemBL item = new ItemBL(itemBase);
  182. ItemDTO itemDto = item.getDTO(language, userId, entityId, currencyId);
  183. BigDecimal percentage = updateLine.getItem().getPercentage();
  184. BigDecimal base = itemDto.getPrice();
  185. BigDecimal result = base.divide(new BigDecimal("100"), Constants.BIGDECIMAL_SCALE, Constants.BIGDECIMAL_ROUND)
  186. .multiply(percentage).add(updateLine.getAmount());
  187. updateLine.setAmount(result);
  188. return updateLine;
  189. }
  190. /**
  191. * Adds or updates an order line. Calculates a percentage item order
  192. * line amount based on the amount of another order line. This is added
  193. * to the existing percentage order line's amount.
  194. */
  195. public OrderLineDTO percentageOnOrderLine(Integer percentageItemId,
  196. OrderLineDTO line) throws TaskException {
  197. // try to get percentage item order line
  198. OrderLineDTO percentageLine = order.getLine(percentageItemId);
  199. if (percentageLine == null) {
  200. // add percentage item
  201. percentageLine = addItem(percentageItemId);
  202. percentageLine.setAmount(BigDecimal.ZERO);
  203. percentageLine.setTotalReadOnly(true);
  204. }
  205. // now add the percentage amount based on the order line item amount
  206. BigDecimal percentage = percentageLine.getItem().getPercentage();
  207. BigDecimal base = line.getPrice().multiply(line.getQuantity());
  208. BigDecimal result = base.divide(new BigDecimal("100"), Constants.BIGDECIMAL_SCALE,
  209. Constants.BIGDECIMAL_ROUND).multiply(percentage).add(percentageLine.getAmount());
  210. percentageLine.setAmount(result);
  211. return percentageLine;
  212. }
  213. public OrderDTO createOrder(Integer itemId, Double quantity) throws TaskException {
  214. BigDecimal quant = new BigDecimal(quantity).setScale(Constants.BIGDECIMAL_SCALE, Constants.BIGDECIMAL_ROUND);
  215. return createOrder(itemId, quant);
  216. }
  217. public OrderDTO createOrder(Integer itemId, BigDecimal quantity)
  218. throws TaskException {
  219. // copy the current order
  220. OrderDTO newOrder = new OrderDTO(order);
  221. newOrder.setId(0);
  222. newOrder.setVersionNum(null);
  223. // the period needs to be in the session
  224. newOrder.setOrderPeriodId(order.getOrderPeriod().getId());
  225. // the status should be active
  226. newOrder.setOrderStatus(new OrderStatusDAS().find(Constants.ORDER_STATUS_ACTIVE));
  227. // but without the lines
  228. newOrder.getLines().clear();
  229. // but do get the new line in
  230. OrderManager helper = new OrderManager(newOrder, language, userId, entityId, currencyId);
  231. OrderLineDTO newLine = helper.addItem(itemId, quantity);
  232. newLine.setPurchaseOrder(newOrder);
  233. newLine.setDefaults();
  234. return new OrderDAS().save(newOrder);
  235. }
  236. public void removeOrder(Integer itemId) {
  237. List<OrderLineDTO> list = new OrderLineDAS().findByUserItem(
  238. order.getBaseUserByUserId().getId(), itemId);
  239. for (OrderLineDTO line : list) {
  240. LOG.debug("Deleting order " + line.getPurchaseOrder().getId());
  241. // who is the executor? we'll use the owner.. she is cancelling
  242. new OrderBL(line.getPurchaseOrder()).delete(order.getBaseUserByUserId().getId());
  243. }
  244. }
  245. public Integer getCurrencyId() {
  246. return currencyId;
  247. }
  248. public Integer getEntityId() {
  249. return entityId;
  250. }
  251. public Integer getLanguage() {
  252. return language;
  253. }
  254. public Integer getUserId() {
  255. return userId;
  256. }
  257. }
  258. }