1 24 package org.ofbiz.accounting.payment; 25 26 import java.util.HashMap ; 27 import java.util.Iterator ; 28 import java.util.LinkedList ; 29 import java.util.List ; 30 import java.util.Map ; 31 import java.util.TreeMap ; 32 import java.math.BigDecimal ; 33 34 import javolution.util.FastList; 35 36 import org.ofbiz.accounting.invoice.InvoiceWorker; 37 import org.ofbiz.base.util.Debug; 38 import org.ofbiz.base.util.GeneralException; 39 import org.ofbiz.base.util.UtilMisc; 40 import org.ofbiz.base.util.UtilNumber; 41 import org.ofbiz.entity.GenericDelegator; 42 import org.ofbiz.entity.GenericEntityException; 43 import org.ofbiz.entity.GenericEntity; 44 import org.ofbiz.entity.GenericValue; 45 import org.ofbiz.entity.condition.EntityCondition; 46 import org.ofbiz.entity.condition.EntityConditionList; 47 import org.ofbiz.entity.condition.EntityExpr; 48 import org.ofbiz.entity.condition.EntityOperator; 49 import org.ofbiz.entity.util.EntityUtil; 50 import org.ofbiz.order.order.OrderReadHelper; 51 import org.ofbiz.service.DispatchContext; 52 import org.ofbiz.service.LocalDispatcher; 53 import org.ofbiz.service.ServiceUtil; 54 55 63 public class BillingAccountWorker { 64 65 public static final String module = BillingAccountWorker.class.getName(); 66 private static BigDecimal ZERO = new BigDecimal ("0"); 67 private static int decimals = -1; 68 private static int rounding = -1; 69 static { 70 decimals = UtilNumber.getBigDecimalScale("order.decimals"); 71 rounding = UtilNumber.getBigDecimalRoundingMode("order.rounding"); 72 73 if (decimals != -1) ZERO.setScale(decimals); 75 } 76 77 public static List makePartyBillingAccountList(GenericValue userLogin, String currencyUomId, String partyId, GenericDelegator delegator, LocalDispatcher dispatcher) throws GeneralException { 78 List billingAccountList = FastList.newInstance(); 79 80 Map agentResult = dispatcher.runSync("getRelatedParties", UtilMisc.toMap("userLogin", userLogin, "partyIdFrom", partyId, 81 "roleTypeIdFrom", "AGENT", "roleTypeIdTo", "CUSTOMER", "partyRelationshipTypeId", "AGENT", "includeFromToSwitched", "Y")); 82 if (ServiceUtil.isError(agentResult)) { 83 throw new GeneralException("Error while finding party BillingAccounts when getting Customers that this party is an agent of: " + ServiceUtil.getErrorMessage(agentResult)); 84 } 85 List relatedPartyIdList = (List ) agentResult.get("relatedPartyIdList"); 86 87 EntityCondition barFindCond = new EntityConditionList(UtilMisc.toList( 88 new EntityExpr("partyId", EntityOperator.IN, relatedPartyIdList), 89 new EntityExpr("roleTypeId", EntityOperator.EQUALS, "BILL_TO_CUSTOMER")), EntityOperator.AND); 90 List billingAccountRoleList = delegator.findByCondition("BillingAccountRole", barFindCond, null, null); 91 billingAccountRoleList = EntityUtil.filterByDate(billingAccountRoleList); 92 93 if (billingAccountRoleList != null && billingAccountRoleList.size() > 0) { 94 double totalAvailable = 0.0; 95 TreeMap sortedAccounts = new TreeMap (); 96 Iterator billingAcctIter = billingAccountRoleList.iterator(); 97 while (billingAcctIter.hasNext()) { 98 GenericValue billingAccountRole = (GenericValue) billingAcctIter.next(); 99 GenericValue billingAccountVO = billingAccountRole.getRelatedOne("BillingAccount"); 100 if (currencyUomId.equals(billingAccountVO.getString("accountCurrencyUomId"))) { 101 double accountBalance = (BillingAccountWorker.getBillingAccountBalance(billingAccountVO)).doubleValue(); 102 103 Map billingAccount = new HashMap (billingAccountVO); 104 double accountLimit = getAccountLimit(billingAccountVO).doubleValue(); 105 106 billingAccount.put("accountBalance", new Double (accountBalance)); 107 double accountAvailable = accountLimit - accountBalance; 108 totalAvailable += accountAvailable; 109 sortedAccounts.put(new Double (accountAvailable), billingAccount); 110 } 111 } 112 113 billingAccountList.addAll(sortedAccounts.values()); 114 } 115 return billingAccountList; 116 } 117 118 123 public static BigDecimal getAccountLimit(GenericValue billingAccount) throws GenericEntityException { 124 if (billingAccount.getBigDecimal("accountLimit") != null) { 125 return billingAccount.getBigDecimal("accountLimit"); 126 } else { 127 Debug.logWarning("Billing Account [" + billingAccount.getString("billingAccountId") + "] does not have an account limit defined, assuming zero.", module); 128 return ZERO; 129 } 130 } 131 132 141 public static BigDecimal getBillingAccountBalance(GenericValue billingAccount) throws GenericEntityException { 142 GenericDelegator delegator = billingAccount.getDelegator(); 143 String billingAccountId = billingAccount.getString("billingAccountId"); 144 145 BigDecimal balance = getBillingAccountNetBalance(delegator, billingAccountId); 147 148 List orderHeaders = null; 150 List exprs1 = new LinkedList (); 151 exprs1.add(new EntityExpr("billingAccountId", EntityOperator.EQUALS, billingAccountId)); 152 exprs1.add(new EntityExpr("statusId", EntityOperator.NOT_EQUAL, "ORDER_REJECTED")); 153 exprs1.add(new EntityExpr("statusId", EntityOperator.NOT_EQUAL, "ORDER_CANCELLED")); 154 exprs1.add(new EntityExpr("statusId", EntityOperator.NOT_EQUAL, "ORDER_COMPLETED")); 155 156 orderHeaders = delegator.findByAnd("OrderHeader", exprs1); 157 158 if (orderHeaders != null) { 159 Iterator ohi = orderHeaders.iterator(); 160 while (ohi.hasNext()) { 161 GenericValue orderHeader = (GenericValue) ohi.next(); 162 OrderReadHelper orh = new OrderReadHelper(orderHeader); 163 balance = balance.add(orh.getOrderGrandTotalBd()); 164 } 165 } 166 167 BigDecimal accountLimit = new BigDecimal (billingAccount.getDouble("accountLimit").doubleValue()); 171 if (balance.compareTo(accountLimit) == 1) { 172 balance = accountLimit; 173 } else { 174 balance = balance.setScale(decimals, rounding); 175 } 176 return balance; 177 } 178 179 public static BigDecimal getBillingAccountBalance(GenericDelegator delegator, String billingAccountId) throws GenericEntityException { 180 GenericValue billingAccount = delegator.findByPrimaryKey("BillingAccount", UtilMisc.toMap("billingAccountId", billingAccountId)); 181 return getBillingAccountBalance(billingAccount); 182 } 183 184 191 public static BigDecimal getBillingAccountAvailableBalance(GenericValue billingAccount) throws GenericEntityException { 192 if ((billingAccount != null) && (billingAccount.get("accountLimit") != null)) { 193 BigDecimal accountLimit = new BigDecimal (billingAccount.getDouble("accountLimit").doubleValue()); 194 BigDecimal availableBalance = accountLimit.subtract(getBillingAccountBalance(billingAccount)).setScale(decimals, rounding); 195 return availableBalance; 196 } else { 197 return ZERO; 198 } 199 } 200 201 209 public static BigDecimal getBillingAccountNetBalance(GenericDelegator delegator, String billingAccountId) throws GenericEntityException { 210 BigDecimal balance = ZERO; 211 212 List paymentAppls = delegator.findByAnd("PaymentApplication", UtilMisc.toMap("billingAccountId", billingAccountId)); 214 if (paymentAppls != null) { 215 for (Iterator pAi = paymentAppls.iterator(); pAi.hasNext(); ) { 216 GenericValue paymentAppl = (GenericValue) pAi.next(); 217 BigDecimal amountApplied = paymentAppl.getBigDecimal("amountApplied"); 218 if (paymentAppl.getString("invoiceId") != null) { 219 if (!"INVOICE_CANCELED".equals(paymentAppl.getRelatedOne("Invoice").getString("statusId"))) { 221 balance = balance.add(amountApplied); 222 } 223 } else { 224 balance = balance.subtract(amountApplied); 225 } 226 } 227 } 228 229 balance = balance.setScale(decimals, rounding); 230 return balance; 231 } 232 233 239 public static BigDecimal availableToCapture(GenericValue billingAccount) throws GenericEntityException { 240 BigDecimal netBalance = getBillingAccountNetBalance(billingAccount.getDelegator(), billingAccount.getString("billingAccountId")); 241 BigDecimal accountLimit = new BigDecimal (billingAccount.getDouble("accountLimit").doubleValue()); 242 243 return accountLimit.subtract(netBalance).setScale(decimals, rounding); 244 } 245 246 public static Map calcBillingAccountBalance(DispatchContext dctx, Map context) { 247 GenericDelegator delegator = dctx.getDelegator(); 248 String billingAccountId = (String ) context.get("billingAccountId"); 249 Map result = ServiceUtil.returnSuccess(); 250 251 try { 252 GenericValue billingAccount = delegator.findByPrimaryKey("BillingAccount", UtilMisc.toMap("billingAccountId", billingAccountId)); 253 if (billingAccount == null) { 254 return ServiceUtil.returnError("Unable to locate billing account #" + billingAccountId); 255 } 256 257 result.put("billingAccount", billingAccount); 258 result.put("accountBalance", new Double ((getBillingAccountBalance(delegator, billingAccountId)).doubleValue())); 259 result.put("netAccountBalance", new Double ((getBillingAccountNetBalance(delegator, billingAccountId)).doubleValue())); 260 result.put("availableBalance", new Double (getBillingAccountAvailableBalance(billingAccount).doubleValue())); 261 result.put("availableToCapture", new Double (availableToCapture(billingAccount).doubleValue())); 262 263 return result; 264 } catch (GenericEntityException e) { 265 Debug.logError(e, module); 266 return ServiceUtil.returnError("Error getting billing account or calculating balance for billing account #" + billingAccountId); 267 } 268 269 270 } 271 } 272 | Popular Tags |