001: /*
002: Licensed to the Apache Software Foundation (ASF) under one
003: or more contributor license agreements. See the NOTICE file
004: distributed with this work for additional information
005: regarding copyright ownership. The ASF licenses this file
006: to you under the Apache License, Version 2.0 (the
007: "License"); you may not use this file except in compliance
008: with the License. You may obtain a copy of the License at
009:
010: http://www.apache.org/licenses/LICENSE-2.0
011:
012: Unless required by applicable law or agreed to in writing,
013: software distributed under the License is distributed on an
014: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: KIND, either express or implied. See the License for the
016: specific language governing permissions and limitations
017: under the License.
018: */
019:
020: package org.ofbiz.accounting.finaccount;
021:
022: import org.ofbiz.service.DispatchContext;
023: import org.ofbiz.service.LocalDispatcher;
024: import org.ofbiz.service.ServiceUtil;
025: import org.ofbiz.service.GenericServiceException;
026: import org.ofbiz.entity.GenericDelegator;
027: import org.ofbiz.entity.GenericValue;
028: import org.ofbiz.entity.GenericEntityException;
029: import org.ofbiz.entity.util.EntityUtil;
030: import org.ofbiz.base.util.*;
031: import org.ofbiz.base.util.string.FlexibleStringExpander;
032: import org.ofbiz.order.order.OrderReadHelper;
033: import org.ofbiz.order.finaccount.FinAccountHelper;
034:
035: import java.util.*;
036: import java.math.BigDecimal;
037:
038: import javolution.util.FastMap;
039:
040: /**
041: * FinAccountProductServices - Financial Accounts created from product purchases (i.e. gift certificates)
042: */
043: public class FinAccountProductServices {
044:
045: public static final String module = FinAccountProductServices.class
046: .getName();
047:
048: public static Map createPartyFinAccountFromPurchase(
049: DispatchContext dctx, Map context) {
050: // this service should always be called via FULFILLMENT_EXTASYNC
051: LocalDispatcher dispatcher = dctx.getDispatcher();
052: GenericDelegator delegator = dctx.getDelegator();
053:
054: GenericValue orderItem = (GenericValue) context
055: .get("orderItem");
056: GenericValue userLogin = (GenericValue) context
057: .get("userLogin");
058:
059: // order ID for tracking
060: String orderId = orderItem.getString("orderId");
061: String orderItemSeqId = orderItem.getString("orderItemSeqId");
062:
063: // the order header for store info
064: GenericValue orderHeader;
065: try {
066: orderHeader = orderItem.getRelatedOne("OrderHeader");
067: } catch (GenericEntityException e) {
068: Debug.logError(e,
069: "Unable to get OrderHeader from OrderItem", module);
070: return ServiceUtil
071: .returnError("Unable to get OrderHeader from OrderItem");
072: }
073:
074: String productId = orderItem.getString("productId");
075: GenericValue featureAndAppl;
076: try {
077: List featureAndAppls = delegator.findByAnd(
078: "ProductFeatureAndAppl", UtilMisc.toMap(
079: "productId", productId,
080: "productFeatureTypeId", "TYPE",
081: "productFeatureApplTypeId",
082: "STANDARD_FEATURE"));
083: featureAndAppls = EntityUtil.filterByDate(featureAndAppls);
084: featureAndAppl = EntityUtil.getFirst(featureAndAppls);
085: } catch (GenericEntityException e) {
086: Debug.logError(e, module);
087: return ServiceUtil.returnError(e.getMessage());
088: }
089:
090: // financial account data; pulled from the TYPE feature of the product
091: String finAccountTypeId = "BALANCE_ACCOUNT"; // default
092: String finAccountName = "Customer Financial Account";
093: if (featureAndAppl != null) {
094: if (UtilValidate.isNotEmpty(featureAndAppl
095: .getString("idCode"))) {
096: finAccountTypeId = featureAndAppl.getString("idCode");
097: }
098: if (UtilValidate.isNotEmpty(featureAndAppl
099: .getString("description"))) {
100: finAccountName = featureAndAppl
101: .getString("description");
102: }
103: }
104:
105: // locate the financial account type
106: GenericValue finAccountType;
107: try {
108: finAccountType = delegator.findByPrimaryKey(
109: "FinAccountType", UtilMisc.toMap(
110: "finAccountTypeId", finAccountTypeId));
111: } catch (GenericEntityException e) {
112: Debug.logError(e, module);
113: return ServiceUtil.returnError(e.getMessage());
114: }
115: String replenishEnumId = finAccountType
116: .getString("replenishEnumId");
117:
118: // get the order read helper
119: OrderReadHelper orh = new OrderReadHelper(orderHeader);
120:
121: // get the currency
122: String currency = orh.getCurrency();
123:
124: // make sure we have a currency
125: if (currency == null) {
126: currency = UtilProperties.getPropertyValue(
127: "general.properties", "currency.uom.id.default",
128: "USD");
129: }
130:
131: // get the product store
132: String productStoreId = null;
133: if (orderHeader != null) {
134: productStoreId = orh.getProductStoreId();
135: }
136: if (productStoreId == null) {
137: return ServiceUtil
138: .returnError("Unable to create financial account; no productStoreId on OrderHeader : "
139: + orderId);
140: }
141:
142: // party ID (owner)
143: GenericValue billToParty = orh.getBillToParty();
144: String partyId = null;
145: if (billToParty != null) {
146: partyId = billToParty.getString("partyId");
147: }
148:
149: // payment method info
150: List payPrefs = orh.getPaymentPreferences();
151: String paymentMethodId = null;
152: if (payPrefs != null) {
153: Iterator i = payPrefs.iterator();
154: while (i.hasNext()) {
155: // needs to be a CC or EFT account
156: GenericValue pref = (GenericValue) i.next();
157: String type = pref.getString("paymentMethodTypeId");
158: if ("CREDIT_CARD".equals(type)
159: || "EFT_ACCOUNT".equals(type)) {
160: paymentMethodId = pref.getString("paymentMethodId");
161: }
162: }
163: }
164: // some person data for expanding
165: GenericValue partyGroup = null;
166: GenericValue person = null;
167: GenericValue party = null;
168:
169: if (billToParty != null) {
170: try {
171: party = billToParty.getRelatedOne("Party");
172: } catch (GenericEntityException e) {
173: Debug.logError(e, module);
174: }
175: if (party != null) {
176: String partyTypeId = party.getString("partyTypeId");
177: if ("PARTY_GROUP".equals(partyTypeId)) {
178: partyGroup = billToParty;
179: } else if ("PERSON".equals(partyTypeId)) {
180: person = billToParty;
181: }
182: }
183: }
184:
185: // create the context for FSE
186: Map expContext = FastMap.newInstance();
187: expContext.put("orderHeader", orderHeader);
188: expContext.put("orderItem", orderItem);
189: expContext.put("party", party);
190: expContext.put("person", person);
191: expContext.put("partyGroup", partyGroup);
192:
193: // expand the name field to dynamicly add information
194: FlexibleStringExpander exp = new FlexibleStringExpander(
195: finAccountName);
196: finAccountName = exp.expandString(expContext);
197:
198: // price/amount/quantity to create initial deposit amount
199: BigDecimal quantity = orderItem.getBigDecimal("quantity");
200: BigDecimal price = orderItem.getBigDecimal("unitPrice");
201: BigDecimal deposit = price.multiply(quantity).setScale(
202: FinAccountHelper.decimals, FinAccountHelper.rounding);
203:
204: // create the financial account
205: Map createCtx = FastMap.newInstance();
206: String finAccountId;
207:
208: createCtx.put("finAccountTypeId", finAccountTypeId);
209: createCtx.put("finAccountName", finAccountName);
210: createCtx.put("productStoreId", productStoreId);
211: createCtx.put("ownerPartyId", partyId);
212: createCtx.put("currencyUomId", currency);
213: createCtx.put("isFrozen", "N");
214: createCtx.put("userLogin", userLogin);
215:
216: // if we auto-replenish this type; set the level to the initial deposit
217: if (replenishEnumId != null
218: && "FARP_AUTOMATIC".equals(replenishEnumId)) {
219: createCtx.put("replenishLevel", new Double(deposit
220: .doubleValue()));
221: createCtx.put("replenishPaymentId", paymentMethodId);
222: }
223:
224: Map createResp;
225: try {
226: createResp = dispatcher.runSync("createFinAccountForStore",
227: createCtx);
228: } catch (GenericServiceException e) {
229: Debug.logError(e, module);
230: return ServiceUtil.returnError(e.getMessage());
231: }
232: if (ServiceUtil.isError(createResp)) {
233: return createResp;
234: } else {
235: finAccountId = (String) createResp.get("finAccountId");
236: }
237:
238: // create the owner role
239: Map roleCtx = FastMap.newInstance();
240: roleCtx.put("partyId", partyId);
241: roleCtx.put("roleTypeId", "OWNER");
242: roleCtx.put("finAccountId", finAccountId);
243: roleCtx.put("userLogin", userLogin);
244: roleCtx.put("fromDate", UtilDateTime.nowTimestamp());
245: Map roleResp;
246: try {
247: roleResp = dispatcher.runSync("createFinAccountRole",
248: roleCtx);
249: } catch (GenericServiceException e) {
250: Debug.logError(e, module);
251: return ServiceUtil.returnError(e.getMessage());
252: }
253: if (ServiceUtil.isError(roleResp)) {
254: return roleResp;
255: }
256:
257: // create the initial deposit
258: Map depositCtx = FastMap.newInstance();
259: depositCtx.put("finAccountId", finAccountId);
260: depositCtx.put("productStoreId", productStoreId);
261: depositCtx.put("currency", currency);
262: depositCtx.put("partyId", partyId);
263: depositCtx.put("orderId", orderId);
264: depositCtx.put("orderItemSeqId", orderItemSeqId);
265: depositCtx.put("amount", new Double(deposit.doubleValue()));
266: depositCtx.put("userLogin", userLogin);
267:
268: Map depositResp;
269: try {
270: depositResp = dispatcher.runSync("finAccountDeposit",
271: depositCtx);
272: } catch (GenericServiceException e) {
273: Debug.logError(e, module);
274: return ServiceUtil.returnError(e.getMessage());
275: }
276: if (ServiceUtil.isError(depositResp)) {
277: return depositResp;
278: }
279:
280: Map result = ServiceUtil.returnSuccess();
281: result.put("finAccountId", finAccountId);
282: return result;
283: }
284: }
|