| /* |
| 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; |
| } |
| } |