📄 billingaccountworker.java
字号:
/* * $Id: BillingAccountWorker.java 7251 2006-04-10 05:39:15Z jacopo $ * * Copyright (c) 2003-2005 The Open For Business Project - www.ofbiz.org * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * THE USE OR OTHER DEALINGS IN THE SOFTWARE. */package org.ofbiz.accounting.payment;import java.util.HashMap;import java.util.Iterator;import java.util.LinkedList;import java.util.List;import java.util.Map;import java.util.TreeMap;import java.math.BigDecimal;import javolution.util.FastList;import org.ofbiz.accounting.invoice.InvoiceWorker;import org.ofbiz.base.util.Debug;import org.ofbiz.base.util.GeneralException;import org.ofbiz.base.util.UtilMisc;import org.ofbiz.base.util.UtilNumber;import org.ofbiz.entity.GenericDelegator;import org.ofbiz.entity.GenericEntityException;import org.ofbiz.entity.GenericEntity;import org.ofbiz.entity.GenericValue;import org.ofbiz.entity.condition.EntityCondition;import org.ofbiz.entity.condition.EntityConditionList;import org.ofbiz.entity.condition.EntityExpr;import org.ofbiz.entity.condition.EntityOperator;import org.ofbiz.entity.util.EntityUtil;import org.ofbiz.order.order.OrderReadHelper;import org.ofbiz.service.DispatchContext;import org.ofbiz.service.LocalDispatcher;import org.ofbiz.service.ServiceUtil;/** * Worker methods for BillingAccounts * * @author <a href="mailto:jaz@ofbiz.org">Andy Zeneski</a> * @author <a href="mailto:jonesde@ofbiz.org">David E. Jones</a> * @version $Rev: 7251 $ * @since 2.1 */public class BillingAccountWorker { public static final String module = BillingAccountWorker.class.getName(); private static BigDecimal ZERO = new BigDecimal("0"); private static int decimals = -1; private static int rounding = -1; static { decimals = UtilNumber.getBigDecimalScale("order.decimals"); rounding = UtilNumber.getBigDecimalRoundingMode("order.rounding"); // set zero to the proper scale if (decimals != -1) ZERO.setScale(decimals); } public static List makePartyBillingAccountList(GenericValue userLogin, String currencyUomId, String partyId, GenericDelegator delegator, LocalDispatcher dispatcher) throws GeneralException { List billingAccountList = FastList.newInstance(); Map agentResult = dispatcher.runSync("getRelatedParties", UtilMisc.toMap("userLogin", userLogin, "partyIdFrom", partyId, "roleTypeIdFrom", "AGENT", "roleTypeIdTo", "CUSTOMER", "partyRelationshipTypeId", "AGENT", "includeFromToSwitched", "Y")); if (ServiceUtil.isError(agentResult)) { throw new GeneralException("Error while finding party BillingAccounts when getting Customers that this party is an agent of: " + ServiceUtil.getErrorMessage(agentResult)); } List relatedPartyIdList = (List) agentResult.get("relatedPartyIdList"); EntityCondition barFindCond = new EntityConditionList(UtilMisc.toList( new EntityExpr("partyId", EntityOperator.IN, relatedPartyIdList), new EntityExpr("roleTypeId", EntityOperator.EQUALS, "BILL_TO_CUSTOMER")), EntityOperator.AND); List billingAccountRoleList = delegator.findByCondition("BillingAccountRole", barFindCond, null, null); billingAccountRoleList = EntityUtil.filterByDate(billingAccountRoleList); if (billingAccountRoleList != null && billingAccountRoleList.size() > 0) { double totalAvailable = 0.0; TreeMap sortedAccounts = new TreeMap(); Iterator billingAcctIter = billingAccountRoleList.iterator(); while (billingAcctIter.hasNext()) { GenericValue billingAccountRole = (GenericValue) billingAcctIter.next(); GenericValue billingAccountVO = billingAccountRole.getRelatedOne("BillingAccount"); if (currencyUomId.equals(billingAccountVO.getString("accountCurrencyUomId"))) { double accountBalance = (BillingAccountWorker.getBillingAccountBalance(billingAccountVO)).doubleValue(); Map billingAccount = new HashMap(billingAccountVO); double accountLimit = 0.0; if (billingAccountVO.getDouble("accountLimit") != null) { accountLimit = billingAccountVO.getDouble("accountLimit").doubleValue(); } billingAccount.put("accountBalance", new Double(accountBalance)); double accountAvailable = accountLimit - accountBalance; totalAvailable += accountAvailable; sortedAccounts.put(new Double(accountAvailable), billingAccount); } } billingAccountList.addAll(sortedAccounts.values()); } return billingAccountList; } /** * Calculates the "available" balance of a billing account, which is net balance minus amount of pending (not canceled, rejected, or completed) orders. * Available balance will not exceed billing account's accountLimit. * When looking at using a billing account for a new order, you should use this method. * @param delegator * @param billingAccountId * @return * @throws GenericEntityException */ public static BigDecimal getBillingAccountBalance(GenericValue billingAccount) throws GenericEntityException { GenericDelegator delegator = billingAccount.getDelegator(); String billingAccountId = billingAccount.getString("billingAccountId"); // first get the net balance of invoices - payments BigDecimal balance = getBillingAccountNetBalance(delegator, billingAccountId); // now the amounts of all the pending orders (not cancelled, rejected or completed) List orderHeaders = null; List exprs1 = new LinkedList(); exprs1.add(new EntityExpr("billingAccountId", EntityOperator.EQUALS, billingAccountId)); exprs1.add(new EntityExpr("statusId", EntityOperator.NOT_EQUAL, "ORDER_REJECTED")); exprs1.add(new EntityExpr("statusId", EntityOperator.NOT_EQUAL, "ORDER_CANCELLED")); exprs1.add(new EntityExpr("statusId", EntityOperator.NOT_EQUAL, "ORDER_COMPLETED")); orderHeaders = delegator.findByAnd("OrderHeader", exprs1); if (orderHeaders != null) { Iterator ohi = orderHeaders.iterator(); while (ohi.hasNext()) { GenericValue orderHeader = (GenericValue) ohi.next(); OrderReadHelper orh = new OrderReadHelper(orderHeader); balance = balance.add(orh.getOrderGrandTotalBd()); } } // set the balance to BillingAccount.accountLimit if it is greater. This is necessary because nowhere do we track the amount of BillingAccount // to be charged to an order, such as FinAccountAuth entity does for FinAccount. As a result, we must assume that the system is doing things correctly // and use the accountLimit BigDecimal accountLimit = new BigDecimal(billingAccount.getDouble("accountLimit").doubleValue()); if (balance.compareTo(accountLimit) == 1) { balance = accountLimit; } else { balance = balance.setScale(decimals, rounding); } return balance; } public static BigDecimal getBillingAccountBalance(GenericDelegator delegator, String billingAccountId) throws GenericEntityException { GenericValue billingAccount = delegator.findByPrimaryKey("BillingAccount", UtilMisc.toMap("billingAccountId", billingAccountId)); return getBillingAccountBalance(billingAccount); } /** * Returns the amount which could be charged to a billing account, which is defined as the accountLimit minus account balance and minus the balance of outstanding orders * When trying to figure out how much of a billing account can be used to pay for an outstanding order, use this method * @param billingAccount * @return * @throws GenericEntityException */ public static BigDecimal getBillingAccountAvailableBalance(GenericValue billingAccount) throws GenericEntityException { if ((billingAccount != null) && (billingAccount.get("accountLimit") != null)) { BigDecimal accountLimit = new BigDecimal(billingAccount.getDouble("accountLimit").doubleValue()); BigDecimal availableBalance = accountLimit.subtract(getBillingAccountBalance(billingAccount)).setScale(decimals, rounding); return availableBalance; } else { return ZERO; } } /** * Calculates the net balance of a billing account, which is sum of all amounts applied to invoices minus sum of all amounts applied from payments. * When charging or capturing an invoice to a billing account, use this method * @param delegator * @param billingAccountId * @return * @throws GenericEntityException */ public static BigDecimal getBillingAccountNetBalance(GenericDelegator delegator, String billingAccountId) throws GenericEntityException { BigDecimal balance = ZERO; // search through all PaymentApplications and add the amount that was applied to invoice and subtract the amount applied from payments List paymentAppls = delegator.findByAnd("PaymentApplication", UtilMisc.toMap("billingAccountId", billingAccountId)); if (paymentAppls != null) { for (Iterator pAi = paymentAppls.iterator(); pAi.hasNext(); ) { GenericValue paymentAppl = (GenericValue) pAi.next(); BigDecimal amountApplied = paymentAppl.getBigDecimal("amountApplied"); if (paymentAppl.getString("invoiceId") != null) { // make sure the invoice has not been canceled if (!"INVOICE_CANCELED".equals(paymentAppl.getRelatedOne("Invoice").getString("statusId"))) { balance = balance.add(amountApplied); } } else { balance = balance.subtract(amountApplied); } } } balance = balance.setScale(decimals, rounding); return balance; } /** * Returns the amount of the billing account which could be captured, which is BillingAccount.accountLimit - net balance * @param billingAccount * @return * @throws GenericEntityException */ public static BigDecimal availableToCapture(GenericValue billingAccount) throws GenericEntityException { BigDecimal netBalance = getBillingAccountNetBalance(billingAccount.getDelegator(), billingAccount.getString("billingAccountId")); BigDecimal accountLimit = new BigDecimal(billingAccount.getDouble("accountLimit").doubleValue()); return accountLimit.subtract(netBalance).setScale(decimals, rounding); } public static Map calcBillingAccountBalance(DispatchContext dctx, Map context) { GenericDelegator delegator = dctx.getDelegator(); String billingAccountId = (String) context.get("billingAccountId"); Map result = ServiceUtil.returnSuccess(); try { GenericValue billingAccount = delegator.findByPrimaryKey("BillingAccount", UtilMisc.toMap("billingAccountId", billingAccountId)); if (billingAccount == null) { return ServiceUtil.returnError("Unable to locate billing account #" + billingAccountId); } result.put("billingAccount", billingAccount); result.put("accountBalance", new Double((getBillingAccountBalance(delegator, billingAccountId)).doubleValue())); result.put("netAccountBalance", new Double((getBillingAccountNetBalance(delegator, billingAccountId)).doubleValue())); result.put("availableBalance", new Double(getBillingAccountAvailableBalance(billingAccount).doubleValue())); result.put("availableToCapture", new Double(availableToCapture(billingAccount).doubleValue())); return result; } catch (GenericEntityException e) { Debug.logError(e, module); return ServiceUtil.returnError("Error getting billing account or calculating balance for billing account #" + billingAccountId); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -