You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by mo...@apache.org on 2009/06/04 19:32:02 UTC

svn commit: r781804 - in /ofbiz/trunk: applications/accounting/data/ applications/order/config/ applications/order/src/org/ofbiz/order/order/ applications/order/webapp/ordermgr/WEB-INF/actions/return/ applications/order/webapp/ordermgr/return/ applicat...

Author: mor
Date: Thu Jun  4 17:32:02 2009
New Revision: 781804

URL: http://svn.apache.org/viewvc?rev=781804&view=rev
Log:
Added a field to ProductStore to specify Store Credit Account type (FIN_ACCOUNT or BILLING_ACCOUNT) for refund return. For Demo ProductStore it is default to Financial Account.
The work flow is based on following steps:
1) If for a return both finAccountId and billingAccountId are supplied, then preference goes to the setting on Product Store. A warning message is shown so that the 
   user know which account is used.
2) If a finAcccountId is supplied then first billing account with -ve amount are searched and if it is found then amount is credit to the billing account else it goes to 
   financial account.
3) If a billingAccountId is supplied then it is used to credit the refund amount.
4) If none of them is supplied, then preference again goes to the setting on Product Store.

Patch applied from Mridul Pathak, part of OFBIZ-2502 (https://issues.apache.org/jira/browse/OFBIZ-2502)

Modified:
    ofbiz/trunk/applications/accounting/data/AccountingTypeData.xml
    ofbiz/trunk/applications/order/config/OrderErrorUiLabels.xml
    ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderReturnServices.java
    ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnHeader.groovy
    ofbiz/trunk/applications/order/webapp/ordermgr/return/ReturnForms.xml
    ofbiz/trunk/applications/product/entitydef/entitymodel.xml
    ofbiz/trunk/applications/product/webapp/catalog/store/ProductStoreForms.xml
    ofbiz/trunk/specialpurpose/ecommerce/data/DemoFinAccount.xml
    ofbiz/trunk/specialpurpose/ecommerce/data/DemoProduct.xml

Modified: ofbiz/trunk/applications/accounting/data/AccountingTypeData.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/accounting/data/AccountingTypeData.xml?rev=781804&r1=781803&r2=781804&view=diff
==============================================================================
--- ofbiz/trunk/applications/accounting/data/AccountingTypeData.xml (original)
+++ ofbiz/trunk/applications/accounting/data/AccountingTypeData.xml Thu Jun  4 17:32:02 2009
@@ -993,4 +993,9 @@
         DDQ (Delivered Duty Unpaid)
         This arrangement is basically the same as with DDP, except for the fact that the buyer is responsible for the duty, fees and taxes.
     -->
+    
+    <!-- Store Credit Account Type Data, to be set in Product Store -->
+    <EnumerationType description="Store Credit Account" enumTypeId="STR_CRDT_ACT" hasTable="N" parentTypeId=""/>
+    <Enumeration description="Financial Account" enumCode="FINACCOUNT" enumId="FIN_ACCOUNT" sequenceId="01" enumTypeId="STR_CRDT_ACT"/>
+    <Enumeration description="Billing Account" enumCode="BILLACCOUNT" enumId="BILLING_ACCOUNT" sequenceId="02" enumTypeId="STR_CRDT_ACT"/>
 </entity-engine-xml>

Modified: ofbiz/trunk/applications/order/config/OrderErrorUiLabels.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/config/OrderErrorUiLabels.xml?rev=781804&r1=781803&r2=781804&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/config/OrderErrorUiLabels.xml (original)
+++ ofbiz/trunk/applications/order/config/OrderErrorUiLabels.xml Thu Jun  4 17:32:02 2009
@@ -1071,6 +1071,9 @@
         <value xml:lang="th">ไม่มียอดรวมของบัญชี</value>
         <value xml:lang="zh">没有可用的账单账户</value>
     </property>
+    <property key="OrderNoAvailableFinAccount">
+        <value xml:lang="en">No available fin account</value>
+    </property>
     <property key="OrderNoCategorySpecifiedToAddFrom">
         <value xml:lang="en">No category specified to add from. </value>
         <value xml:lang="es">Ninguna categoría especificada a partir de la cual agregar.</value>
@@ -1335,6 +1338,15 @@
         <value xml:lang="th">กรุณาเลือกถ้าไม่การขายหรือรายการสั่งซื้อ</value>
         <value xml:lang="zh">请选择销售或购物订单。 </value>
     </property>
+    <property key="OrderProblemsCreatingFinAccountForStore">
+        <value xml:lang="en">Problems creating FinAccount for Store</value>
+    </property>
+    <property key="OrderProblemCreatingFinAccountRoleRecord">
+        <value xml:lang="en">Problem creating FinAccountRole record</value>
+    </property>
+    <property key="OrderProblemCreatingFinAccountTransRecord">
+        <value xml:lang="en">Problem creating FinAccountTrans record</value>
+    </property>
     <property key="OrderProblemCreatingPaymentApplicationRecord">
         <value xml:lang="en">Problem creating PaymentApplication record</value>
         <value xml:lang="es">Problema creando el registro de solicitud de pago</value>

Modified: ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderReturnServices.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderReturnServices.java?rev=781804&r1=781803&r2=781804&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderReturnServices.java (original)
+++ ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderReturnServices.java Thu Jun  4 17:32:02 2009
@@ -28,6 +28,7 @@
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.ListIterator;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
@@ -678,7 +679,7 @@
         Locale locale = (Locale) context.get("locale");
 
         GenericValue returnHeader = null;
-        List returnItems = null;
+        List<GenericValue> returnItems = null;
         try {
             returnHeader = delegator.findByPrimaryKey("ReturnHeader", UtilMisc.toMap("returnId", returnId));
             if (returnHeader != null) {
@@ -692,6 +693,7 @@
         BigDecimal adjustments = getReturnAdjustmentTotal(delegator, UtilMisc.toMap("returnId", returnId, "returnTypeId", "RTN_CREDIT"));
 
         if (returnHeader != null && ((returnItems != null && returnItems.size() > 0) || adjustments.compareTo(ZERO) > 0)) {
+            String finAccountId = returnHeader.getString("finAccountId");
             String billingAccountId = returnHeader.getString("billingAccountId");
             String fromPartyId = returnHeader.getString("fromPartyId");
             String toPartyId = returnHeader.getString("toPartyId");
@@ -707,20 +709,129 @@
             if (ServiceUtil.isError(serviceResult)) {
                 return ServiceUtil.returnError(ServiceUtil.getErrorMessage(serviceResult));
             }
-            if (billingAccountId == null) {
-                // create new BillingAccount w/ 0 balance
-                Map results = createBillingAccountFromReturn(returnHeader, returnItems, dctx, context);
-                if (ServiceUtil.isError(results)) {
-                    Debug.logError("Error creating BillingAccount: " + results.get(ModelService.ERROR_MESSAGE), module);
-                    return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorWithCreateBillingAccount", locale) + results.get(ModelService.ERROR_MESSAGE));
-                }
-                billingAccountId = (String) results.get("billingAccountId");
+
+            // Fetch the ProductStore
+            GenericValue productStore = null;
+            GenericValue orderHeader = null;
+            GenericValue returnItem = EntityUtil.getFirst(returnItems);
+            try {
+                orderHeader = returnItem.getRelatedOne("OrderHeader");
+            } catch (GenericEntityException e) {
+                return ServiceUtil.returnError(e.getMessage());
+            }
+            if (orderHeader != null) {
+                OrderReadHelper orderReadHelper = new OrderReadHelper(orderHeader);
+                productStore = orderReadHelper.getProductStore();
             }
 
-            // double check; make sure we have a billingAccount
-            if (billingAccountId == null) {
-                Debug.logError("No available billing account, none was created", module);
-                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderNoAvailableBillingAccount", locale));
+            // if both billingAccountId and finAccountId are supplied, look for productStore.storeCreditAccountEnumId preference
+            if (finAccountId != null && billingAccountId != null) {
+                Debug.logWarning("FinAccount and BillingAccount both are supplied for storing credit, priority will be given to ProductStore preference. Default is FinAccount.", module);
+                if (productStore != null && productStore.getString("storeCreditAccountEnumId") != null && "BILLING_ACCOUNT".equals(productStore.getString("storeCreditAccountEnumId"))) {
+                    finAccountId = null;
+                } else {
+                    billingAccountId = null;
+                }
+            }
+
+            if (finAccountId == null && billingAccountId == null) {
+                // First find a Billing Account with negative balance, and if found store credit to that
+                List<GenericValue> billingAccounts = FastList.newInstance();
+                try {
+                    billingAccounts = delegator.findByAnd("BillingAccountRoleAndAddress", UtilMisc.toMap("partyId", fromPartyId, "roleTypeId", "BILL_TO_CUSTOMER"));
+                } catch (GenericEntityException e) {
+                    return ServiceUtil.returnError(e.getMessage());
+                }
+                billingAccounts = EntityUtil.filterByDate(billingAccounts);
+                billingAccounts = EntityUtil.orderBy(billingAccounts, UtilMisc.toList("-fromDate"));
+                if (UtilValidate.isNotEmpty(billingAccounts)) {
+                    ListIterator<GenericValue> billingAccountItr = billingAccounts.listIterator();
+                    while (billingAccountItr.hasNext() && billingAccountId == null) {
+                        String thisBillingAccountId = billingAccountItr.next().getString("billingAccountId");
+                        BigDecimal billingAccountBalance = ZERO;
+                        try {
+                            billingAccountBalance = getBillingAccountBalance(thisBillingAccountId, dctx);
+                        } catch (GenericEntityException e) {
+                            return ServiceUtil.returnError(e.getMessage());
+                        }
+                        if (billingAccountBalance.signum() == -1) {
+                            billingAccountId = thisBillingAccountId;
+                        }
+                    }
+                }
+
+                // if no billing account with negative balance is found, look for productStore.storeCreditAccountEnumId settings
+                if (billingAccountId == null) {
+                    if (productStore != null && productStore.getString("storeCreditAccountEnumId") != null && "BILLING_ACCOUNT".equals(productStore.getString("storeCreditAccountEnumId"))) {
+                        if (UtilValidate.isNotEmpty(billingAccounts)) {
+                            billingAccountId = EntityUtil.getFirst(billingAccounts).getString("billingAccountId");
+                        } else {
+                            // create new BillingAccount w/ 0 balance
+                            Map results = createBillingAccountFromReturn(returnHeader, returnItems, dctx, context);
+                            if (ServiceUtil.isError(results)) {
+                                Debug.logError("Error creating BillingAccount: " + results.get(ModelService.ERROR_MESSAGE), module);
+                                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorWithCreateBillingAccount", locale) + results.get(ModelService.ERROR_MESSAGE));
+                            }
+                            billingAccountId = (String) results.get("billingAccountId");
+
+                            // double check; make sure we have a billingAccount
+                            if (billingAccountId == null) {
+                                Debug.logError("No available billing account, none was created", module);
+                                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderNoAvailableBillingAccount", locale));
+                            }
+                        }
+                    } else {
+                        List<GenericValue> finAccounts = null;
+                        try {
+                            finAccounts = delegator.findByAnd("FinAccountAndRole", UtilMisc.toMap("partyId", fromPartyId, "finAccountTypeId", "STORE_CREDIT_ACCT", "roleTypeId", "OWNER", "statusId", "FNACT_ACTIVE"));
+                        } catch (GenericEntityException e) {
+                            return ServiceUtil.returnError(e.getMessage());
+                        }
+                        finAccounts = EntityUtil.filterByDate(finAccounts);
+                        finAccounts = EntityUtil.orderBy(finAccounts, UtilMisc.toList("-fromDate"));
+                        if (UtilValidate.isNotEmpty(finAccounts)) {
+                            finAccountId = EntityUtil.getFirst(finAccounts).getString("finAccountId");
+                        }
+
+                        if (finAccountId == null) {
+                            Map createAccountCtx = FastMap.newInstance();
+                            createAccountCtx.put("ownerPartyId", fromPartyId);
+                            createAccountCtx.put("finAccountTypeId", "STORE_CREDIT_ACCT");
+                            createAccountCtx.put("productStoreId", productStore.getString("productStoreId"));
+                            createAccountCtx.put("currencyUomId", returnHeader.getString("currencyUomId"));
+                            createAccountCtx.put("finAccountName", "Store Credit Account for party ["+fromPartyId+"]");
+                            createAccountCtx.put("userLogin", userLogin);
+                            Map createAccountResult = null;
+                            try {
+                                createAccountResult = dispatcher.runSync("createFinAccountForStore", createAccountCtx);
+                            } catch (GenericServiceException e) {
+                                Debug.logError(e, "Problems running the createFinAccountForStore service", module);
+                                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemsCreatingFinAccountForStore", locale));
+                            }
+                            if (ServiceUtil.isError(createAccountResult)) {
+                                return ServiceUtil.returnError(ServiceUtil.getErrorMessage(createAccountResult));
+                            }
+                            finAccountId = (String) createAccountResult.get("finAccountId");
+
+                            // double check; make sure we have a FinAccount
+                            if (finAccountId == null) {
+                                Debug.logError("No available fin account, none was created", module);
+                                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderNoAvailableFinAccount", locale));
+                            }
+
+                            Map finAccountRoleResult = null;
+                            try {
+                                finAccountRoleResult = dispatcher.runSync("createFinAccountRole", UtilMisc.toMap("finAccountId", finAccountId, "partyId", fromPartyId, "roleTypeId", "OWNER", "userLogin", userLogin));
+                            } catch (GenericServiceException e) {
+                                Debug.logError(e, "Problem running the createFinAccountRole service", module);
+                                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemCreatingFinAccountRoleRecord", locale));
+                            }
+                            if (ServiceUtil.isError(finAccountRoleResult)) {
+                                return ServiceUtil.returnError(ServiceUtil.getErrorMessage(finAccountRoleResult));
+                            }
+                        }
+                    }
+                }
             }
 
             // now; to be used for all timestamps
@@ -740,19 +851,39 @@
             // add the adjustments to the total
             creditTotal = creditTotal.add(adjustments.setScale(decimals, rounding));
 
+            // create finAccountRole and finAccountTrans
+            String finAccountTransId = null;
+            if (finAccountId != null) {
+                Map finAccountTransResult = null;
+                try {
+                    finAccountTransResult = dispatcher.runSync("createFinAccountTrans", UtilMisc.toMap("finAccountId", finAccountId, "finAccountTransTypeId", "DEPOSIT", "partyId", toPartyId, "amount", creditTotal, "reasonEnumId", "FATR_REFUND", "userLogin", userLogin));
+                } catch (GenericServiceException e) {
+                    Debug.logError(e, "Problem creating FinAccountTrans record", module);
+                    return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemCreatingFinAccountTransRecord", locale));
+                }
+                if (ServiceUtil.isError(finAccountTransResult)) {
+                    return ServiceUtil.returnError(ServiceUtil.getErrorMessage(finAccountTransResult));
+                }
+                finAccountTransId = (String) finAccountTransResult.get("finAccountTransId");
+            }
+
             // create a Payment record for this credit; will look just like a normal payment
             // However, since this payment is not a DISBURSEMENT or RECEIPT but really a matter of internal record
             // it is of type "Other (Non-posting)"
             String paymentId = delegator.getNextSeqId("Payment");
             GenericValue payment = delegator.makeValue("Payment", UtilMisc.toMap("paymentId", paymentId));
             payment.set("paymentTypeId", "CUSTOMER_REFUND");
-            payment.set("paymentMethodTypeId", "EXT_BILLACT");
             payment.set("partyIdFrom", toPartyId);  // if you receive a return FROM someone, then you'd have to give a return TO that person
             payment.set("partyIdTo", fromPartyId);
             payment.set("effectiveDate", now);
             payment.set("amount", creditTotal);
             payment.set("comments", "Return Credit");
             payment.set("statusId", "PMNT_CONFIRMED");  // set the status to confirmed so nothing else can happen to the payment
+            if (billingAccountId != null) {
+                payment.set("paymentMethodTypeId", "EXT_BILLACT");
+            } else {
+                payment.set("paymentMethodTypeId", "FIN_ACCOUNT");
+            }
             try {
                 delegator.create(payment);
             } catch (GenericEntityException e) {
@@ -762,10 +893,14 @@
 
             // create a return item response
             Map itemResponse = UtilMisc.toMap("paymentId", paymentId);
-            itemResponse.put("billingAccountId", billingAccountId);
             itemResponse.put("responseAmount", creditTotal);
             itemResponse.put("responseDate", now);
             itemResponse.put("userLogin", userLogin);
+            if (billingAccountId != null) {
+                itemResponse.put("billingAccountId", billingAccountId);
+            } else {
+                itemResponse.put("finAccountTransId", finAccountTransId);
+            }
             Map serviceResults = null;
             try {
                 serviceResults = dispatcher.runSync("createReturnItemResponse", itemResponse);
@@ -796,34 +931,83 @@
                 }
             }
 
-            // create the PaymentApplication for the billing account
-            String paId = delegator.getNextSeqId("PaymentApplication");
-            GenericValue pa = delegator.makeValue("PaymentApplication", UtilMisc.toMap("paymentApplicationId", paId));
-            pa.set("paymentId", paymentId);
-            pa.set("billingAccountId", billingAccountId);
-            pa.set("amountApplied", creditTotal);
-            try {
-                delegator.create(pa);
-            } catch (GenericEntityException e) {
-                Debug.logError(e, "Problem creating PaymentApplication record for billing account", module);
-                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemCreatingPaymentApplicationRecord", locale));
-            }
+            if (billingAccountId != null) {
+                // create the PaymentApplication for the billing account
+                String paId = delegator.getNextSeqId("PaymentApplication");
+                GenericValue pa = delegator.makeValue("PaymentApplication", UtilMisc.toMap("paymentApplicationId", paId));
+                pa.set("paymentId", paymentId);
+                pa.set("billingAccountId", billingAccountId);
+                pa.set("amountApplied", creditTotal);
+                try {
+                    delegator.create(pa);
+                } catch (GenericEntityException e) {
+                    Debug.logError(e, "Problem creating PaymentApplication record for billing account", module);
+                    return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemCreatingPaymentApplicationRecord", locale));
+                }
 
-            // create the payment applications for the return invoice
-            try {
-                serviceResults = dispatcher.runSync("createPaymentApplicationsFromReturnItemResponse",
-                        UtilMisc.<String, Object>toMap("returnItemResponseId", itemResponseId, "userLogin", userLogin));
-                if (ServiceUtil.isError(serviceResults)) {
-                    return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemCreatingPaymentApplicationRecord", locale), null, null, serviceResults);
+                // create the payment applications for the return invoice in case of billing account
+                try {
+                    serviceResults = dispatcher.runSync("createPaymentApplicationsFromReturnItemResponse",
+                            UtilMisc.<String, Object>toMap("returnItemResponseId", itemResponseId, "userLogin", userLogin));
+                    if (ServiceUtil.isError(serviceResults)) {
+                        return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemCreatingPaymentApplicationRecord", locale), null, null, serviceResults);
+                    }
+                } catch (GenericServiceException e) {
+                    Debug.logError(e, "Problem creating PaymentApplication records for return invoice", module);
+                    return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemCreatingPaymentApplicationRecord", locale));
                 }
-            } catch (GenericServiceException e) {
-                Debug.logError(e, "Problem creating PaymentApplication records for return invoice", module);
-                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemCreatingPaymentApplicationRecord", locale));
             }
         }
 
         return ServiceUtil.returnSuccess();
     }
+    
+    /**
+     * Helper method to get billing account balance, cannot use BillingAccountWorker.getBillingAccountBalance()
+     * due to circular build dependency.
+     * @param billingAccountId
+     * @param dctx
+     * @return
+     * @throws GenericEntityException
+     */
+    public static BigDecimal getBillingAccountBalance(String billingAccountId, DispatchContext dctx) throws GenericEntityException {
+        GenericDelegator delegator = dctx.getDelegator();
+        GenericValue billingAccount = delegator.findByPrimaryKey("BillingAccount", UtilMisc.toMap("billingAccountId", billingAccountId));
+
+        BigDecimal balance = ZERO;
+        BigDecimal accountLimit = ZERO;
+        if (billingAccount.getBigDecimal("accountLimit") != null) {
+            accountLimit = billingAccount.getBigDecimal("accountLimit");
+        }
+        balance = balance.add(accountLimit);
+        // pending (not cancelled, rejected, or received) order payments
+        EntityConditionList whereConditions = EntityCondition.makeCondition(UtilMisc.toList(
+                EntityCondition.makeCondition("billingAccountId", EntityOperator.EQUALS, billingAccountId),
+                EntityCondition.makeCondition("paymentMethodTypeId", EntityOperator.EQUALS, "EXT_BILLACT"),
+                EntityCondition.makeCondition("statusId", EntityOperator.NOT_IN, UtilMisc.toList("ORDER_CANCELLED", "ORDER_REJECTED")),
+                EntityCondition.makeCondition("preferenceStatusId", EntityOperator.NOT_IN, UtilMisc.toList("PAYMENT_SETTLED", "PAYMENT_RECEIVED", "PAYMENT_DECLINED", "PAYMENT_CANCELLED")) // PAYMENT_NOT_AUTH
+            ), EntityOperator.AND);
+
+        List orderPaymentPreferenceSums = delegator.findList("OrderPurchasePaymentSummary", whereConditions, UtilMisc.toSet("maxAmount"), null, null, false);
+        for (Iterator oppsi = orderPaymentPreferenceSums.iterator(); oppsi.hasNext(); ) {
+            GenericValue orderPaymentPreferenceSum = (GenericValue) oppsi.next();
+            BigDecimal maxAmount = orderPaymentPreferenceSum.getBigDecimal("maxAmount");
+            balance = maxAmount != null ? balance.subtract(maxAmount) : balance;
+        }
+
+        List paymentAppls = delegator.findByAnd("PaymentApplication", UtilMisc.toMap("billingAccountId", billingAccountId));
+        // TODO: cancelled payments?
+        for (Iterator pAi = paymentAppls.iterator(); pAi.hasNext(); ) {
+            GenericValue paymentAppl = (GenericValue) pAi.next();
+            if (paymentAppl.getString("invoiceId") == null) {
+                BigDecimal amountApplied = paymentAppl.getBigDecimal("amountApplied");
+                balance = balance.add(amountApplied);
+            }
+        }
+
+        balance = balance.setScale(decimals, rounding);
+        return balance;
+    }
 
     /**
      * Helper method to generate a BillingAccount (store credit) from a return

Modified: ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnHeader.groovy
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnHeader.groovy?rev=781804&r1=781803&r2=781804&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnHeader.groovy (original)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnHeader.groovy Thu Jun  4 17:32:02 2009
@@ -57,6 +57,14 @@
 context.returnHeader = returnHeader;
 context.returnId = returnId;
 
+//fin account info
+finAccounts = null;
+if (partyId) {
+    finAccounts = delegator.findByAnd("FinAccountAndRole", [partyId: partyId, finAccountTypeId: "STORE_CREDIT_ACCT", roleTypeId: "OWNER", statusId: "FNACT_ACTIVE"]);
+    finAccounts = EntityUtil.filterByDate(finAccounts);
+}
+context.finAccounts = finAccounts;
+
 // billing account info
 billingAccountList = null;
 if (partyId) {

Modified: ofbiz/trunk/applications/order/webapp/ordermgr/return/ReturnForms.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/return/ReturnForms.xml?rev=781804&r1=781803&r2=781804&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/return/ReturnForms.xml (original)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/return/ReturnForms.xml Thu Jun  4 17:32:02 2009
@@ -87,6 +87,11 @@
                 <list-options key-name="billingAccountId" list-name="billingAccountList" description="${billingAccountId}: ${description}"/>
             </drop-down>
         </field>
+        <field name="finAccountId" use-when="finAccounts!=null&amp;&amp;finAccounts.size()&gt;0">
+            <drop-down allow-empty="true">
+                <list-options key-name="finAccountId" list-name="finAccounts" description="${finAccountId}: ${finAccountName}"/>
+            </drop-down>
+        </field>
         <field name="paymentMethodId" use-when="creditCardList!=null&amp;&amp;creditCardList.size()&gt;0">
             <drop-down allow-empty="true">
                 <list-options list-name="creditCardList" list-entry-name="creditCardPm" key-name="creditCardPm.paymentMethodId" description="${bsh:org.ofbiz.party.contact.ContactHelper.formatCreditCard(creditCardPm.getRelatedOne(&quot;CreditCard&quot;))}"/>

Modified: ofbiz/trunk/applications/product/entitydef/entitymodel.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/entitydef/entitymodel.xml?rev=781804&r1=781803&r2=781804&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/entitydef/entitymodel.xml (original)
+++ ofbiz/trunk/applications/product/entitydef/entitymodel.xml Thu Jun  4 17:32:02 2009
@@ -3608,6 +3608,12 @@
       <field name="authFraudMessage" type="long-varchar"></field>
       <field name="authErrorMessage" type="long-varchar"></field>
       <field name="visualThemeId" type="id"></field>
+      <field name="storeCreditAccountEnumId" type="id">
+          <description>Specify the type (Billing Account or Financial Account) of Store Credit Account used for refund return. Default to Financial Account. 
+              This field is override by ReturnHeader.billingAccountId or ReturnHeader.finAccountId, whichever is specified but if only finAccountId is specified explicitly then system will first
+              try to locate any billing account with -ve amount. If found, then amount is credit to this billing account else the amount will be credit to the financial account of the user.
+          </description>
+      </field>
 
       <!-- old fields, deprecated -->
       <field name="oldStyleSheet" col-name="STYLE_SHEET" type="url"></field>
@@ -3690,6 +3696,9 @@
         <key-map field-name="vatTaxAuthGeoId" rel-field-name="taxAuthGeoId"/>
         <key-map field-name="vatTaxAuthPartyId" rel-field-name="taxAuthPartyId"/>
       </relation>
+      <relation type="one" fk-name="PROD_STR_STRCRDACT" title="StoreCreditAccount" rel-entity-name="Enumeration">
+        <key-map field-name="storeCreditAccountEnumId" rel-field-name="enumId"/>
+      </relation>
     </entity>
     <entity entity-name="ProductStoreCatalog"
             package-name="org.ofbiz.product.store"

Modified: ofbiz/trunk/applications/product/webapp/catalog/store/ProductStoreForms.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/webapp/catalog/store/ProductStoreForms.xml?rev=781804&r1=781803&r2=781804&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/webapp/catalog/store/ProductStoreForms.xml (original)
+++ ofbiz/trunk/applications/product/webapp/catalog/store/ProductStoreForms.xml Thu Jun  4 17:32:02 2009
@@ -223,6 +223,14 @@
                 </entity-options>
             </drop-down>
         </field>
+        <field name="storeCreditAccountEnumId">
+            <drop-down allow-empty="false">
+                <entity-options key-field-name="enumId" description="${description}" entity-name="Enumeration">
+                    <entity-constraint name="enumTypeId" operator="equals" value="STR_CRDT_ACT"/>
+                    <entity-order-by field-name="sequenceId"/>
+                </entity-options>
+            </drop-down>
+        </field>
         <field name="oldStyleSheet"><hidden/></field>
         <field name="oldHeaderLogo"><hidden/></field>
         <field name="oldHeaderMiddleBackground"><hidden/></field>

Modified: ofbiz/trunk/specialpurpose/ecommerce/data/DemoFinAccount.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/ecommerce/data/DemoFinAccount.xml?rev=781804&r1=781803&r2=781804&view=diff
==============================================================================
--- ofbiz/trunk/specialpurpose/ecommerce/data/DemoFinAccount.xml (original)
+++ ofbiz/trunk/specialpurpose/ecommerce/data/DemoFinAccount.xml Thu Jun  4 17:32:02 2009
@@ -30,6 +30,9 @@
 
     <ProductStoreFinActSetting productStoreId="9000" finAccountTypeId="REPLENISH_ACCOUNT" requirePinCode="N" validateGCFinAcct="Y" allowAuthToNegative="Y" replenishThreshold="0.0"
         purchaseSurveyId="1100" purchSurveySendTo="recipientEmail" purchSurveyCopyMe="copyMe" accountCodeLength="12" pinCodeLength="4" accountValidDays="365" authValidDays="5"/>
+    
+    <ProductStoreFinActSetting productStoreId="9000" finAccountTypeId="STORE_CREDIT_ACCT" requirePinCode="N" validateGCFinAcct="Y" allowAuthToNegative="Y" replenishThreshold="0.0"
+        purchaseSurveyId="1100" purchSurveySendTo="recipientEmail" purchSurveyCopyMe="copyMe" accountCodeLength="12" pinCodeLength="4" accountValidDays="365" authValidDays="5"/>
 
     <ProductStorePaymentSetting productStoreId="9000" paymentMethodTypeId="FIN_ACCOUNT" paymentServiceTypeEnumId="PRDS_PAY_AUTH" paymentService="ofbFaAuthorize" paymentCustomMethodId="FIN_AUTH_OFBIZ"/>
     <ProductStorePaymentSetting productStoreId="9000" paymentMethodTypeId="FIN_ACCOUNT" paymentServiceTypeEnumId="PRDS_PAY_RELEASE" paymentService="ofbFaRelease" paymentCustomMethodId="FIN_RELEASE_OFBIZ"/>

Modified: ofbiz/trunk/specialpurpose/ecommerce/data/DemoProduct.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/ecommerce/data/DemoProduct.xml?rev=781804&r1=781803&r2=781804&view=diff
==============================================================================
--- ofbiz/trunk/specialpurpose/ecommerce/data/DemoProduct.xml (original)
+++ ofbiz/trunk/specialpurpose/ecommerce/data/DemoProduct.xml Thu Jun  4 17:32:02 2009
@@ -56,7 +56,7 @@
         authDeclinedMessage="There has been a problem with your method of payment. Please try a different method or call customer service."
         authFraudMessage="Your order has been rejected and your account has been disabled due to fraud."
         authErrorMessage="Problem connecting to payment processor; we will continue to retry and notify you by email."
-        storeCreditValidDays="90"
+        storeCreditValidDays="90" storeCreditAccountEnumId="FIN_ACCOUNT"
         visualThemeId="EC_DEFAULT" autoApproveInvoice="Y" shipIfCaptureFails="Y" autoApproveOrder="Y" showOutOfStockProducts="Y"/>
 
     <!-- <ProductStorePaymentSetting productStoreId="9000" paymentMethodTypeId="CREDIT_CARD" paymentServiceTypeEnumId="PRDS_PAY_AUTH" paymentService="testRandomAuthorize"/> -->