blob: 562271726a590e0c790c52fb6f8f9eb4c8ea1406 [file] [log] [blame]
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*******************************************************************************/
package org.ofbiz.product.subscription;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javolution.util.FastMap;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilDateTime;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.common.uom.UomWorker;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.entity.condition.EntityCondition;
import org.ofbiz.entity.condition.EntityOperator;
import org.ofbiz.entity.util.EntityQuery;
import org.ofbiz.entity.util.EntityUtil;
import org.ofbiz.service.DispatchContext;
import org.ofbiz.service.GenericServiceException;
import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.service.ModelService;
import org.ofbiz.service.ServiceUtil;
import com.ibm.icu.util.Calendar;
/**
* Subscription Services
*/
public class SubscriptionServices {
public static final String module = SubscriptionServices.class.getName();
public static final String resource = "ProductUiLabels";
public static final String resourceOrderError = "OrderErrorUiLabels";
public static Map<String, Object> processExtendSubscription(DispatchContext dctx, Map<String, ? extends Object> context) {
Delegator delegator = dctx.getDelegator();
LocalDispatcher dispatcher = dctx.getDispatcher();
Timestamp nowTimestamp = UtilDateTime.nowTimestamp();
String partyId = (String) context.get("partyId");
String subscriptionResourceId = (String) context.get("subscriptionResourceId");
String inventoryItemId = (String) context.get("inventoryItemId");
String roleTypeId = (String) context.get("useRoleTypeId");
GenericValue userLogin = (GenericValue) context.get("userLogin");
Integer useTime = (Integer) context.get("useTime");
String useTimeUomId = (String) context.get("useTimeUomId");
String alwaysCreateNewRecordStr = (String) context.get("alwaysCreateNewRecord");
Locale locale = (Locale) context.get("locale");
boolean alwaysCreateNewRecord = !"N".equals(alwaysCreateNewRecordStr);
GenericValue lastSubscription = null;
try {
Map<String, String> subscriptionFindMap = UtilMisc.toMap("partyId", partyId, "subscriptionResourceId", subscriptionResourceId);
// if this subscription is attached to something the customer owns, filter by that too
if (UtilValidate.isNotEmpty(inventoryItemId)) subscriptionFindMap.put("inventoryItemId", inventoryItemId);
List<GenericValue> subscriptionList = EntityQuery.use(delegator).from("Subscription").where(subscriptionFindMap).queryList();
// DEJ20070718 DON'T filter by date, we want to consider all subscriptions: List listFiltered = EntityUtil.filterByDate(subscriptionList, true);
List<GenericValue> listOrdered = EntityUtil.orderBy(subscriptionList, UtilMisc.toList("-fromDate"));
if (listOrdered.size() > 0) {
lastSubscription = listOrdered.get(0);
}
} catch (GenericEntityException e) {
return ServiceUtil.returnError(e.toString());
}
GenericValue newSubscription = null;
if (lastSubscription == null || alwaysCreateNewRecord) {
newSubscription = delegator.makeValue("Subscription");
newSubscription.set("subscriptionResourceId", subscriptionResourceId);
newSubscription.set("partyId", partyId);
newSubscription.set("roleTypeId", roleTypeId);
newSubscription.set("productId", context.get("productId"));
newSubscription.set("orderId", context.get("orderId"));
newSubscription.set("orderItemSeqId", context.get("orderItemSeqId"));
newSubscription.set("automaticExtend", context.get("automaticExtend"));
newSubscription.set("canclAutmExtTimeUomId", context.get("canclAutmExtTimeUomId"));
newSubscription.set("canclAutmExtTime", context.get("canclAutmExtTime"));
} else {
newSubscription = lastSubscription;
}
newSubscription.set("inventoryItemId", inventoryItemId);
Timestamp thruDate = lastSubscription != null ? (Timestamp) lastSubscription.get("thruDate") : null;
// set the fromDate, one way or another
if (thruDate == null) {
// no thruDate? start with NOW
thruDate = nowTimestamp;
newSubscription.set("fromDate", nowTimestamp);
} else {
// there is a thru date... if it is in the past, bring it up to NOW before adding on the time period
// don't want to penalize for skipping time, in other words if they had a subscription last year for a
// month and buy another month, we want that second month to start now and not last year
if (thruDate.before(nowTimestamp)) {
thruDate = nowTimestamp;
}
newSubscription.set("fromDate", thruDate);
}
Calendar calendar = Calendar.getInstance();
calendar.setTime(thruDate);
int[] times = UomWorker.uomTimeToCalTime(useTimeUomId);
if (times != null) {
calendar.add(times[0], (useTime.intValue() * times[1]));
} else {
Debug.logWarning("Don't know anything about useTimeUomId [" + useTimeUomId + "], defaulting to month", module);
calendar.add(Calendar.MONTH, useTime);
}
thruDate = new Timestamp(calendar.getTimeInMillis());
newSubscription.set("thruDate", thruDate);
Map<String, Object> result = ServiceUtil.returnSuccess();
try {
if (lastSubscription != null && !alwaysCreateNewRecord) {
Map<String, Object> updateSubscriptionMap = dctx.getModelService("updateSubscription").makeValid(newSubscription, ModelService.IN_PARAM);
updateSubscriptionMap.put("userLogin", EntityQuery.use(delegator).from("UserLogin").where("userLoginId", "system").queryOne());
Map<String, Object> updateSubscriptionResult = dispatcher.runSync("updateSubscription", updateSubscriptionMap);
result.put("subscriptionId", updateSubscriptionMap.get("subscriptionId"));
if (ServiceUtil.isError(updateSubscriptionResult)) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ProductSubscriptionUpdateError",
UtilMisc.toMap("subscriptionId", updateSubscriptionMap.get("subscriptionId")), locale),
null, null, updateSubscriptionResult);
}
} else {
Map<String, Object> ensurePartyRoleMap = FastMap.newInstance();
if (UtilValidate.isNotEmpty(roleTypeId)) {
ensurePartyRoleMap.put("partyId", partyId);
ensurePartyRoleMap.put("roleTypeId", roleTypeId);
ensurePartyRoleMap.put("userLogin", userLogin);
Map<String, Object> ensurePartyRoleResult = dispatcher.runSync("ensurePartyRole", ensurePartyRoleMap);
if (ServiceUtil.isError(ensurePartyRoleResult)) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ProductSubscriptionPartyRoleCreationError",
UtilMisc.toMap("subscriptionResourceId", subscriptionResourceId), locale),
null, null, ensurePartyRoleResult);
}
}
Map<String, Object> createSubscriptionMap = dctx.getModelService("createSubscription").makeValid(newSubscription, ModelService.IN_PARAM);
createSubscriptionMap.put("userLogin", EntityQuery.use(delegator).from("UserLogin").where("userLoginId", "system").queryOne());
Map<String, Object> createSubscriptionResult = dispatcher.runSync("createSubscription", createSubscriptionMap);
if (ServiceUtil.isError(createSubscriptionResult)) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ProductSubscriptionCreateError",
UtilMisc.toMap("subscriptionResourceId", subscriptionResourceId), locale),
null, null, createSubscriptionResult);
}
result.put("subscriptionId", createSubscriptionResult.get("subscriptionId"));
}
} catch (GenericEntityException e) {
return ServiceUtil.returnError(e.toString());
} catch (GenericServiceException e) {
return ServiceUtil.returnError(e.toString());
}
return result;
}
public static Map<String, Object> processExtendSubscriptionByProduct(DispatchContext dctx, Map<String, ? extends Object> context) throws GenericServiceException{
Delegator delegator = dctx.getDelegator();
LocalDispatcher dispatcher = dctx.getDispatcher();
String productId = (String) context.get("productId");
Integer qty = (Integer) context.get("quantity");
Locale locale = (Locale) context.get("locale");
if (qty == null) {
qty = Integer.valueOf(1);
}
Timestamp orderCreatedDate = (Timestamp) context.get("orderCreatedDate");
if (orderCreatedDate == null) {
orderCreatedDate = UtilDateTime.nowTimestamp();
}
try {
List<GenericValue> productSubscriptionResourceList = EntityQuery.use(delegator).from("ProductSubscriptionResource")
.where("productId", productId)
.cache(true)
.filterByDate(orderCreatedDate, "fromDate", "thruDate", "purchaseFromDate", "purchaseThruDate")
.queryList();
if (productSubscriptionResourceList.size() == 0) {
Debug.logError("No ProductSubscriptionResource found for productId: " + productId, module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ProductSubscriptionResourceNotFound",
UtilMisc.toMap("productId", productId), locale));
}
for (GenericValue productSubscriptionResource: productSubscriptionResourceList) {
Long useTime = productSubscriptionResource.getLong("useTime");
Integer newUseTime = Integer.valueOf(0);
if (useTime != null) {
newUseTime = Integer.valueOf(useTime.intValue() * qty.intValue());
}
Map<String, Object> subContext = UtilMisc.makeMapWritable(context);
subContext.put("useTime", newUseTime);
subContext.put("useTimeUomId", productSubscriptionResource.get("useTimeUomId"));
subContext.put("useRoleTypeId", productSubscriptionResource.get("useRoleTypeId"));
subContext.put("subscriptionResourceId", productSubscriptionResource.get("subscriptionResourceId"));
subContext.put("automaticExtend", productSubscriptionResource.get("automaticExtend"));
subContext.put("canclAutmExtTime", productSubscriptionResource.get("canclAutmExtTime"));
subContext.put("canclAutmExtTimeUomId", productSubscriptionResource.get("canclAutmExtTimeUomId"));
subContext.put("gracePeriodOnExpiry", productSubscriptionResource.get("gracePeriodOnExpiry"));
subContext.put("gracePeriodOnExpiryUomId", productSubscriptionResource.get("gracePeriodOnExpiryUomId"));
Map<String, Object> ctx = dctx.getModelService("processExtendSubscription").makeValid(subContext, ModelService.IN_PARAM);
Map<String, Object> processExtendSubscriptionResult = dispatcher.runSync("processExtendSubscription", ctx);
if (ServiceUtil.isError(processExtendSubscriptionResult)) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ProductSubscriptionByProductError",
UtilMisc.toMap("productId", productId), locale),
null, null, processExtendSubscriptionResult);
}
}
} catch (GenericEntityException e) {
Debug.logError(e, e.toString(), module);
return ServiceUtil.returnError(e.toString());
}
return ServiceUtil.returnSuccess();
}
public static Map<String, Object> processExtendSubscriptionByOrder(DispatchContext dctx, Map<String, ? extends Object> context) throws GenericServiceException{
Delegator delegator = dctx.getDelegator();
LocalDispatcher dispatcher = dctx.getDispatcher();
Map<String, Object> subContext = UtilMisc.makeMapWritable(context);
String orderId = (String) context.get("orderId");
Locale locale = (Locale) context.get("locale");
Debug.logInfo("In processExtendSubscriptionByOrder service with orderId: " + orderId, module);
GenericValue orderHeader = null;
try {
List<GenericValue> orderRoleList = EntityQuery.use(delegator).from("OrderRole").where("orderId", orderId, "roleTypeId", "END_USER_CUSTOMER").queryList();
if (orderRoleList.size() > 0) {
GenericValue orderRole = orderRoleList.get(0);
String partyId = (String) orderRole.get("partyId");
subContext.put("partyId", partyId);
} else {
return ServiceUtil.returnFailure(UtilProperties.getMessage(resourceOrderError,
"OrderErrorCannotGetOrderRoleEntity",
UtilMisc.toMap("itemMsgInfo", orderId), locale));
}
orderHeader = EntityQuery.use(delegator).from("OrderHeader").where("orderId", orderId).queryOne();
if (orderHeader == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(resourceOrderError,
"OrderErrorNoValidOrderHeaderFoundForOrderId",
UtilMisc.toMap("orderId", orderId), locale));
}
Timestamp orderCreatedDate = (Timestamp) orderHeader.get("orderDate");
subContext.put("orderCreatedDate", orderCreatedDate);
List<GenericValue> orderItemList = orderHeader.getRelated("OrderItem", null, null, false);
for (GenericValue orderItem: orderItemList) {
BigDecimal qty = orderItem.getBigDecimal("quantity");
String productId = orderItem.getString("productId");
if (UtilValidate.isEmpty(productId)) {
continue;
}
List<GenericValue> productSubscriptionResourceListFiltered = EntityQuery.use(delegator).from("ProductSubscriptionResource").where("productId", productId).cache(true).filterByDate().queryList();
if (productSubscriptionResourceListFiltered.size() > 0) {
subContext.put("subscriptionTypeId", "PRODUCT_SUBSCR");
subContext.put("productId", productId);
subContext.put("orderId", orderId);
subContext.put("orderItemSeqId", orderItem.get("orderItemSeqId"));
subContext.put("inventoryItemId", orderItem.get("fromInventoryItemId"));
subContext.put("quantity", Integer.valueOf(qty.intValue()));
Map<String, Object> ctx = dctx.getModelService("processExtendSubscriptionByProduct").makeValid(subContext, ModelService.IN_PARAM);
Map<String, Object> thisResult = dispatcher.runSync("processExtendSubscriptionByProduct", ctx);
if (ServiceUtil.isError(thisResult)) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ProductSubscriptionByOrderError",
UtilMisc.toMap("orderId", orderId), locale), null, null, thisResult);
}
}
}
} catch (GenericEntityException e) {
Debug.logError(e.toString(), module);
return ServiceUtil.returnError(e.toString());
}
return ServiceUtil.returnSuccess();
}
public static Map<String, Object> runServiceOnSubscriptionExpiry( DispatchContext dctx, Map<String, ? extends Object> context) {
LocalDispatcher dispatcher = dctx.getDispatcher();
Delegator delegator = dctx.getDelegator();
GenericValue userLogin = (GenericValue) context.get("userLogin");
Map<String, Object> result = new HashMap<String, Object>();
Map<String, Object> expiryMap = new HashMap<String, Object>();
String gracePeriodOnExpiry = null;
String gracePeriodOnExpiryUomId = null;
String subscriptionId = null;
Timestamp expirationCompletedDate = null;
try {
EntityCondition cond1 = EntityCondition.makeCondition("automaticExtend", EntityOperator.EQUALS, "N");
EntityCondition cond2 = EntityCondition.makeCondition("automaticExtend", EntityOperator.EQUALS, null);
EntityCondition cond = EntityCondition.makeCondition(UtilMisc.toList(cond1, cond2), EntityOperator.OR);
List<GenericValue> subscriptionList = null;
subscriptionList = EntityQuery.use(delegator).from("Subscription").where(cond).queryList();
if (subscriptionList != null) {
for (GenericValue subscription : subscriptionList) {
expirationCompletedDate = subscription.getTimestamp("expirationCompletedDate");
if (expirationCompletedDate == null) {
Calendar currentDate = Calendar.getInstance();
currentDate.setTime(UtilDateTime.nowTimestamp());
// check if the thruDate + grace period (if provided) is earlier than today's date
Calendar endDateSubscription = Calendar.getInstance();
int field = Calendar.MONTH;
String subscriptionResourceId = subscription.getString("subscriptionResourceId");
GenericValue subscriptionResource = null;
subscriptionResource = EntityQuery.use(delegator).from("SubscriptionResource").where("subscriptionResourceId", subscriptionResourceId).queryOne();
subscriptionId = subscription.getString("subscriptionId");
gracePeriodOnExpiry = subscription.getString("gracePeriodOnExpiry");
gracePeriodOnExpiryUomId = subscription.getString("gracePeriodOnExpiryUomId");
String serviceNameOnExpiry = subscriptionResource.getString("serviceNameOnExpiry");
endDateSubscription.setTime(subscription.getTimestamp("thruDate"));
if (gracePeriodOnExpiry != null && gracePeriodOnExpiryUomId != null) {
if ("TF_day".equals(gracePeriodOnExpiryUomId)) {
field = Calendar.DAY_OF_YEAR;
} else if ("TF_wk".equals(gracePeriodOnExpiryUomId)) {
field = Calendar.WEEK_OF_YEAR;
} else if ("TF_mon".equals(gracePeriodOnExpiryUomId)) {
field = Calendar.MONTH;
} else if ("TF_yr".equals(gracePeriodOnExpiryUomId)) {
field = Calendar.YEAR;
} else {
Debug.logWarning("Don't know anything about gracePeriodOnExpiryUomId [" + gracePeriodOnExpiryUomId + "], defaulting to month", module);
}
endDateSubscription.add(field, Integer.valueOf(gracePeriodOnExpiry).intValue());
}
if ((currentDate.after(endDateSubscription) || currentDate.equals(endDateSubscription)) && serviceNameOnExpiry != null) {
if (userLogin != null) {
expiryMap.put("userLogin", userLogin);
}
if (subscriptionId != null) {
expiryMap.put("subscriptionId", subscriptionId);
}
result = dispatcher.runSync(serviceNameOnExpiry, expiryMap);
if (ServiceUtil.isSuccess(result)) {
subscription.set("expirationCompletedDate", UtilDateTime.nowTimestamp());
delegator.store(subscription);
Debug.logInfo("Subscription expired successfully for subscription ID:" + subscriptionId, module);
} else if (ServiceUtil.isError(result)) {
result = null;
Debug.logError("Error expiring subscription while processing with subscriptionId: " + subscriptionId, module);
}
if (result != null && subscriptionId != null) {
Debug.logInfo("Service mentioned in serviceNameOnExpiry called with result: " + result.get("successMessage"), module);
} else if (result == null && subscriptionId != null) {
Debug.logError("Subscription couldn't be expired for subscriptionId: " + subscriptionId, module);
return ServiceUtil.returnError("Subscription couldn't be expired for subscriptionId: " + subscriptionId);
}
}
}
}
}
} catch (GenericServiceException e) {
Debug.logError("Error while calling service specified in serviceNameOnExpiry", module);
return ServiceUtil.returnError(e.toString());
} catch (GenericEntityException e) {
Debug.logError(e, module);
}
return result;
}
public static Map<String, Object> runSubscriptionExpired(
DispatchContext dctx, Map<String, ? extends Object> context) {
String subscriptionId = (String) context.get("subscriptionId");
Map<String, Object> result = new HashMap<String, Object>();
if (subscriptionId != null) {
return ServiceUtil.returnSuccess("runSubscriptionExpired service called successfully with subscriptionId " + subscriptionId);
}
return result;
}
}