blob: b93a8f701a757c7d73d2c8b4c4a484619f79bb40 [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.accounting.finaccount;
import org.ofbiz.service.DispatchContext;
import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.service.ServiceUtil;
import org.ofbiz.service.GenericServiceException;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.util.EntityUtil;
import org.ofbiz.entity.util.EntityUtilProperties;
import org.ofbiz.base.util.*;
import org.ofbiz.base.util.string.FlexibleStringExpander;
import org.ofbiz.order.order.OrderReadHelper;
import org.ofbiz.order.finaccount.FinAccountHelper;
import java.util.*;
import java.math.BigDecimal;
import javolution.util.FastMap;
/**
* FinAccountProductServices - Financial Accounts created from product purchases (i.e. gift certificates)
*/
public class FinAccountProductServices {
public static final String module = FinAccountProductServices.class.getName();
public static final String resourceOrderError = "OrderErrorUiLabels";
public static final String resourceError = "AccountingErrorUiLabels";
public static Map<String, Object> createPartyFinAccountFromPurchase(DispatchContext dctx, Map<String, Object> context) {
// this service should always be called via FULFILLMENT_EXTASYNC
LocalDispatcher dispatcher = dctx.getDispatcher();
Delegator delegator = dctx.getDelegator();
Locale locale = (Locale) context.get("locale");
GenericValue orderItem = (GenericValue) context.get("orderItem");
GenericValue userLogin = (GenericValue) context.get("userLogin");
// order ID for tracking
String orderId = orderItem.getString("orderId");
String orderItemSeqId = orderItem.getString("orderItemSeqId");
// the order header for store info
GenericValue orderHeader;
try {
orderHeader = orderItem.getRelatedOne("OrderHeader", false);
} catch (GenericEntityException e) {
Debug.logError(e, "Unable to get OrderHeader from OrderItem", module);
return ServiceUtil.returnError(UtilProperties.getMessage(resourceOrderError,
"OrderCannotGetOrderHeader", UtilMisc.toMap("orderId", orderId), locale));
}
String productId = orderItem.getString("productId");
GenericValue featureAndAppl;
try {
List<GenericValue> featureAndAppls = delegator.findByAnd("ProductFeatureAndAppl", UtilMisc.toMap("productId", productId,
"productFeatureTypeId", "TYPE", "productFeatureApplTypeId", "STANDARD_FEATURE"), null, false);
featureAndAppls = EntityUtil.filterByDate(featureAndAppls);
featureAndAppl = EntityUtil.getFirst(featureAndAppls);
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
// financial account data; pulled from the TYPE feature of the product
String finAccountTypeId = "BALANCE_ACCOUNT"; // default
String finAccountName = "Customer Financial Account";
if (featureAndAppl != null) {
if (UtilValidate.isNotEmpty(featureAndAppl.getString("idCode"))) {
finAccountTypeId = featureAndAppl.getString("idCode");
}
if (UtilValidate.isNotEmpty(featureAndAppl.getString("description"))) {
finAccountName = featureAndAppl.getString("description");
}
}
// locate the financial account type
GenericValue finAccountType;
try {
finAccountType = delegator.findOne("FinAccountType", UtilMisc.toMap("finAccountTypeId", finAccountTypeId), false);
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
String replenishEnumId = finAccountType.getString("replenishEnumId");
// get the order read helper
OrderReadHelper orh = new OrderReadHelper(orderHeader);
// get the currency
String currency = orh.getCurrency();
// make sure we have a currency
if (currency == null) {
currency = EntityUtilProperties.getPropertyValue("general.properties", "currency.uom.id.default", "USD", delegator);
}
// get the product store
String productStoreId = null;
if (orderHeader != null) {
productStoreId = orh.getProductStoreId();
}
if (productStoreId == null) {
Debug.logFatal("Unable to create financial accout; no productStoreId on OrderHeader : " + orderId, module);
return ServiceUtil.returnError(UtilProperties.getMessage(resourceError,
"AccountingFinAccountCannotCreate",
UtilMisc.toMap("orderId", orderId), locale));
}
// party ID (owner)
GenericValue billToParty = orh.getBillToParty();
String partyId = null;
if (billToParty != null) {
partyId = billToParty.getString("partyId");
}
// payment method info
List<GenericValue> payPrefs = orh.getPaymentPreferences();
String paymentMethodId = null;
if (payPrefs != null) {
for (GenericValue pref : payPrefs) {
// needs to be a CC or EFT account
String type = pref.getString("paymentMethodTypeId");
if ("CREDIT_CARD".equals(type) || "EFT_ACCOUNT".equals(type)) {
paymentMethodId = pref.getString("paymentMethodId");
}
}
}
// some person data for expanding
GenericValue partyGroup = null;
GenericValue person = null;
GenericValue party = null;
if (billToParty != null) {
try {
party = billToParty.getRelatedOne("Party", false);
} catch (GenericEntityException e) {
Debug.logError(e, module);
}
if (party != null) {
String partyTypeId = party.getString("partyTypeId");
if ("PARTY_GROUP".equals(partyTypeId)) {
partyGroup = billToParty;
} else if ("PERSON".equals(partyTypeId)) {
person = billToParty;
}
}
}
// create the context for FSE
Map<String, Object> expContext = FastMap.newInstance();
expContext.put("orderHeader", orderHeader);
expContext.put("orderItem", orderItem);
expContext.put("party", party);
expContext.put("person", person);
expContext.put("partyGroup", partyGroup);
// expand the name field to dynamically add information
FlexibleStringExpander exp = FlexibleStringExpander.getInstance(finAccountName);
finAccountName = exp.expandString(expContext);
// price/amount/quantity to create initial deposit amount
BigDecimal quantity = orderItem.getBigDecimal("quantity");
BigDecimal price = orderItem.getBigDecimal("unitPrice");
BigDecimal deposit = price.multiply(quantity).setScale(FinAccountHelper.decimals, FinAccountHelper.rounding);
// create the financial account
Map<String, Object> createCtx = FastMap.newInstance();
String finAccountId;
createCtx.put("finAccountTypeId", finAccountTypeId);
createCtx.put("finAccountName", finAccountName);
createCtx.put("productStoreId", productStoreId);
createCtx.put("ownerPartyId", partyId);
createCtx.put("currencyUomId", currency);
createCtx.put("statusId", "FNACT_ACTIVE");
createCtx.put("userLogin", userLogin);
// if we auto-replenish this type; set the level to the initial deposit
if (replenishEnumId != null && "FARP_AUTOMATIC".equals(replenishEnumId)) {
createCtx.put("replenishLevel", deposit);
createCtx.put("replenishPaymentId", paymentMethodId);
}
Map<String, Object> createResp;
try {
createResp = dispatcher.runSync("createFinAccountForStore", createCtx);
} catch (GenericServiceException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
if (ServiceUtil.isError(createResp)) {
Debug.logFatal(ServiceUtil.getErrorMessage(createResp), module);
return createResp;
}
finAccountId = (String) createResp.get("finAccountId");
// create the owner role
Map<String, Object> roleCtx = FastMap.newInstance();
roleCtx.put("partyId", partyId);
roleCtx.put("roleTypeId", "OWNER");
roleCtx.put("finAccountId", finAccountId);
roleCtx.put("userLogin", userLogin);
roleCtx.put("fromDate", UtilDateTime.nowTimestamp());
Map<String, Object> roleResp;
try {
roleResp = dispatcher.runSync("createFinAccountRole", roleCtx);
} catch (GenericServiceException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
if (ServiceUtil.isError(roleResp)) {
Debug.logFatal(ServiceUtil.getErrorMessage(roleResp), module);
return roleResp;
}
// create the initial deposit
Map<String, Object> depositCtx = FastMap.newInstance();
depositCtx.put("finAccountId", finAccountId);
depositCtx.put("productStoreId", productStoreId);
depositCtx.put("currency", currency);
depositCtx.put("partyId", partyId);
depositCtx.put("orderId", orderId);
depositCtx.put("orderItemSeqId", orderItemSeqId);
depositCtx.put("amount", deposit);
depositCtx.put("reasonEnumId", "FATR_IDEPOSIT");
depositCtx.put("userLogin", userLogin);
Map<String, Object> depositResp;
try {
depositResp = dispatcher.runSync("finAccountDeposit", depositCtx);
} catch (GenericServiceException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
if (ServiceUtil.isError(depositResp)) {
Debug.logFatal(ServiceUtil.getErrorMessage(depositResp), module);
return depositResp;
}
Map<String, Object> result = ServiceUtil.returnSuccess();
result.put("finAccountId", finAccountId);
return result;
}
}