You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ja...@apache.org on 2008/07/29 15:28:55 UTC

svn commit: r680690 [1/2] - in /ofbiz/trunk/applications: accounting/config/ accounting/servicedef/ accounting/src/org/ofbiz/accounting/invoice/ order/config/ order/script/org/ofbiz/order/order/ order/servicedef/ order/src/org/ofbiz/order/order/ order/...

Author: jacopoc
Date: Tue Jul 29 06:28:52 2008
New Revision: 680690

URL: http://svn.apache.org/viewvc?rev=680690&view=rev
Log:
Initial version of the supplier return implementation; thanks to Vikas Mayur for the patch that I have committed with two small changes from OFBIZ-1893

Added:
    ofbiz/trunk/applications/order/webapp/ordermgr/images/
    ofbiz/trunk/applications/order/webapp/ordermgr/images/js/
    ofbiz/trunk/applications/order/webapp/ordermgr/images/js/return.js   (with props)
    ofbiz/trunk/applications/product/webapp/facility/WEB-INF/actions/shipment/AddItemsFromInventory.groovy   (with props)
    ofbiz/trunk/applications/product/webapp/facility/shipment/AddItemsFromInventory.ftl   (with props)
Modified:
    ofbiz/trunk/applications/accounting/config/AccountingUiLabels.xml
    ofbiz/trunk/applications/accounting/servicedef/services_invoice.xml
    ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/invoice/InvoiceServices.java
    ofbiz/trunk/applications/order/config/OrderUiLabels.xml
    ofbiz/trunk/applications/order/script/org/ofbiz/order/order/OrderReturnServices.xml
    ofbiz/trunk/applications/order/servicedef/secas.xml
    ofbiz/trunk/applications/order/servicedef/services_return.xml
    ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderReturnServices.java
    ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/return/QuickReturn.groovy
    ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnHeader.groovy
    ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnItems.groovy
    ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/controller.xml
    ofbiz/trunk/applications/order/webapp/ordermgr/return/ReturnForms.xml
    ofbiz/trunk/applications/order/webapp/ordermgr/return/quickReturn.ftl
    ofbiz/trunk/applications/order/webapp/ordermgr/return/returnItems.ftl
    ofbiz/trunk/applications/order/widget/ordermgr/OrderReturnScreens.xml
    ofbiz/trunk/applications/product/config/ProductUiLabels.xml
    ofbiz/trunk/applications/product/entitydef/entitymodel_shipment.xml
    ofbiz/trunk/applications/product/script/org/ofbiz/product/inventory/InventoryServices.xml
    ofbiz/trunk/applications/product/script/org/ofbiz/shipment/issuance/IssuanceServices.xml
    ofbiz/trunk/applications/product/script/org/ofbiz/shipment/shipment/ShipmentServices.xml
    ofbiz/trunk/applications/product/servicedef/secas_shipment.xml
    ofbiz/trunk/applications/product/servicedef/services_facility.xml
    ofbiz/trunk/applications/product/servicedef/services_shipment.xml
    ofbiz/trunk/applications/product/webapp/facility/WEB-INF/controller.xml
    ofbiz/trunk/applications/product/webapp/facility/lookup/FieldLookupForms.xml
    ofbiz/trunk/applications/product/webapp/facility/shipment/ShipmentForms.xml
    ofbiz/trunk/applications/product/webapp/facility/shipment/ShipmentTabBar.ftl
    ofbiz/trunk/applications/product/webapp/facility/shipment/ViewShipmentInfo.ftl
    ofbiz/trunk/applications/product/widget/facility/LookupScreens.xml
    ofbiz/trunk/applications/product/widget/facility/ShipmentScreens.xml

Modified: ofbiz/trunk/applications/accounting/config/AccountingUiLabels.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/accounting/config/AccountingUiLabels.xml?rev=680690&r1=680689&r2=680690&view=diff
==============================================================================
--- ofbiz/trunk/applications/accounting/config/AccountingUiLabels.xml (original)
+++ ofbiz/trunk/applications/accounting/config/AccountingUiLabels.xml Tue Jul 29 06:28:52 2008
@@ -5441,6 +5441,9 @@
         <value xml:lang="th">การส่งสินค้าไม่มีประเภทของ SALES_RETURN</value>
         <value xml:lang="zh">运输不是销售退货(SALES_RETURN)类型。</value>
     </property>
+    <property key="AccountingShipmentNotSalesReturnAndPurchaseReturn">
+        <value xml:lang="en">Shipment is not of type SALES_RETURN and PURCHASE_RETURN.</value>
+    </property>        
     <property key="AccountingShipmentsOfDifferentTypes">
         <value xml:lang="en">Shipments of different types found; shipment [${tmpShipmentId}] of type [${shipmentTypeId}] is of different type from the previous ones.</value>
         <value xml:lang="es">Envíos de diferentes tipos encontratos; envío [${tmpShipmentId}] de tipo [${shipmentTypeId}] es de un tipo distinto a los anteriores.</value>

Modified: ofbiz/trunk/applications/accounting/servicedef/services_invoice.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/accounting/servicedef/services_invoice.xml?rev=680690&r1=680689&r2=680690&view=diff
==============================================================================
--- ofbiz/trunk/applications/accounting/servicedef/services_invoice.xml (original)
+++ ofbiz/trunk/applications/accounting/servicedef/services_invoice.xml Tue Jul 29 06:28:52 2008
@@ -162,7 +162,7 @@
             shipmentReceiptsToBill = List of ShipmentReceipts to use for creating the invoice
         </description>
         <attribute name="returnId" type="String" mode="IN" optional="false"/>
-        <attribute name="shipmentReceiptsToBill" type="List" mode="IN" optional="false"/>
+        <attribute name="billItems" type="List" mode="IN" optional="false"/>
         <attribute name="invoiceId" type="String" mode="OUT" optional="true"/>
     </service>
     <service name="createCommissionInvoices" engine="java"

Modified: ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/invoice/InvoiceServices.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/invoice/InvoiceServices.java?rev=680690&r1=680689&r2=680690&view=diff
==============================================================================
--- ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/invoice/InvoiceServices.java (original)
+++ ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/invoice/InvoiceServices.java Tue Jul 29 06:28:52 2008
@@ -1587,8 +1587,9 @@
 
         String shipmentId = (String) context.get("shipmentId");
         String errorMsg = UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceForShipment",UtilMisc.toMap("shipmentId",shipmentId), locale);
-
-
+        boolean salesReturnFound = false;
+        boolean purchaseReturnFound = false;
+        
         List invoicesCreated = new ArrayList();
         try {
 
@@ -1597,45 +1598,71 @@
             if (shipment == null) {
                 return ServiceUtil.returnError(errorMsg + UtilProperties.getMessage(resource, "AccountingShipmentNotFound",locale));
             }
-            if (!shipment.getString("shipmentTypeId").equals("SALES_RETURN")) {
-                return ServiceUtil.returnError(errorMsg + UtilProperties.getMessage(resource, "AccountingShipmentNotSalesReturn",locale));
-            }
-
-            // get the list of ShipmentReceipt for this shipment
-            List shipmentReceipts = shipment.getRelated("ShipmentReceipt");
+            if (shipment.getString("shipmentTypeId").equals("SALES_RETURN")) {
+                salesReturnFound = true;
+            } else if ("PURCHASE_RETURN".equals(shipment.getString("shipmentTypeId"))) {
+                purchaseReturnFound = true;
+            }
+            if (!(salesReturnFound || purchaseReturnFound)) {
+                 return ServiceUtil.returnError(errorMsg + UtilProperties.getMessage(resource, "AccountingShipmentNotSalesReturnAndPurchaseReturn",locale));
+            }
+            // get the items of the shipment. They can come from ItemIssuance if the shipment were from a purchase return, ShipmentReceipt if it were from a sales return
+            List shippedItems = null;
+            if (salesReturnFound) {
+                shippedItems = shipment.getRelated("ShipmentReceipt");
+            } else if (purchaseReturnFound) {
+                shippedItems = shipment.getRelated("ItemIssuance");
+            }
+            if (shippedItems == null) {
+                Debug.logInfo("No items issued for shipments", module);
+                return ServiceUtil.returnSuccess();
+            }            
 
             // group the shipments by returnId (because we want a seperate itemized invoice for each return)
-            Map receiptsGroupedByReturn = new HashMap();
-            for (Iterator iter = shipmentReceipts.iterator(); iter.hasNext(); ) {
-                GenericValue receipt = (GenericValue) iter.next();
-                String returnId = receipt.getString("returnId");
+            Map itemsShippedGroupedByReturn = FastMap.newInstance();
+            
+            for (Iterator iter = shippedItems.iterator(); iter.hasNext(); ) {
+                GenericValue item = (GenericValue) iter.next();
+                String returnId = null;
+                String returnItemSeqId = null;
+                if (item.getEntityName().equals("ShipmentReceipt")) {
+                    returnId = item.getString("returnId");
+                } else if (item.getEntityName().equals("ItemIssuance")) {
+                    GenericValue returnItemShipment = EntityUtil.getFirst(delegator.findByAnd("ReturnItemShipment", UtilMisc.toMap("shipmentId", item.getString("shipmentId"), "shipmentItemSeqId", item.getString("shipmentItemSeqId"))));
+                    returnId = returnItemShipment.getString("returnId");
+                    returnItemSeqId = returnItemShipment.getString("returnItemSeqId");
+                }
 
                 // see if there are ReturnItemBillings for this item
-                List billings = delegator.findByAnd("ReturnItemBilling", UtilMisc.toMap("shipmentReceiptId", receipt.getString("receiptId"), "returnId", returnId, 
-                            "returnItemSeqId", receipt.get("returnItemSeqId")));
-
+                List billings = null;
+                if (item.getEntityName().equals("ShipmentReceipt")) {
+                    billings = delegator.findByAnd("ReturnItemBilling", UtilMisc.toMap("shipmentReceiptId", item.getString("receiptId"), "returnId", returnId, 
+                                "returnItemSeqId", item.get("returnItemSeqId")));
+                } else if (item.getEntityName().equals("ItemIssuance")) {
+                    billings = delegator.findByAnd("ReturnItemBilling", UtilMisc.toMap("returnId", returnId, "returnItemSeqId", returnItemSeqId));
+                }
                 // if there are billings, we have already billed the item, so skip it
                 if (billings.size() > 0) continue;
 
-                // get the List of receipts keyed to this returnId or create a new one
-                List receipts = (List) receiptsGroupedByReturn.get(returnId);
-                if (receipts == null) {
-                    receipts = new ArrayList();
+                // get the List of items shipped to/from this returnId
+                List billItems = (List) itemsShippedGroupedByReturn.get(returnId);
+                if (billItems == null) {
+                    billItems = new ArrayList();
                 }
 
                 // add our item to the group and put it back in the map
-                receipts.add(receipt);
-                receiptsGroupedByReturn.put(returnId, receipts);
+                billItems.add(item);
+                itemsShippedGroupedByReturn.put(returnId, billItems);
             }
 
             // loop through the returnId keys in the map and invoke the createInvoiceFromReturn service for each
-            for (Iterator iter = receiptsGroupedByReturn.keySet().iterator(); iter.hasNext(); ) {
+            for (Iterator iter = itemsShippedGroupedByReturn.keySet().iterator(); iter.hasNext(); ) {
                 String returnId = (String) iter.next();
-                List receipts = (List) receiptsGroupedByReturn.get(returnId);
+                List billItems = (List) itemsShippedGroupedByReturn.get(returnId);
                 if (Debug.verboseOn()) {
-                    Debug.logVerbose("Creating invoice for return [" + returnId + "] with receipts: " + receipts.toString(), module);
+                    Debug.logVerbose("Creating invoice for return [" + returnId + "] with items: " + billItems.toString(), module);
                 }
-                Map input = UtilMisc.toMap("returnId", returnId, "shipmentReceiptsToBill", receipts, "userLogin", context.get("userLogin"));
+                Map input = UtilMisc.toMap("returnId", returnId, "billItems", billItems, "userLogin", context.get("userLogin"));
                 Map serviceResults = dispatcher.runSync("createInvoiceFromReturn", input);
                 if (ServiceUtil.isError(serviceResults)) {
                     return ServiceUtil.returnError(errorMsg, null, null, serviceResults);
@@ -1664,20 +1691,28 @@
         Locale locale = (Locale) context.get("locale");
 
         String returnId= (String) context.get("returnId");
-        List receipts = (List) context.get("shipmentReceiptsToBill");
+        List billItems = (List) context.get("billItems");
         String errorMsg = UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceForReturn",UtilMisc.toMap("returnId",returnId),locale);
         // List invoicesCreated = new ArrayList();
         try {
+            String invoiceTypeId;
+            String description;
             // get the return header
             GenericValue returnHeader = delegator.findByPrimaryKey("ReturnHeader", UtilMisc.toMap("returnId", returnId));
-
+            if ("CUSTOMER_RETURN".equals(returnHeader.getString("returnHeaderTypeId"))) {
+                invoiceTypeId = "CUST_RTN_INVOICE";
+                description = "Return Invoice for Customer Return #" + returnId;
+            } else {
+                invoiceTypeId = "PURC_RTN_INVOICE";
+                description = "Return Invoice for Vendor Return #" + returnId;
+            }
             // set the invoice data
-            Map input = UtilMisc.toMap("invoiceTypeId", "CUST_RTN_INVOICE", "statusId", "INVOICE_IN_PROCESS");
+            Map input = UtilMisc.toMap("invoiceTypeId", invoiceTypeId, "statusId", "INVOICE_IN_PROCESS");
             input.put("partyId", returnHeader.get("toPartyId"));
             input.put("partyIdFrom", returnHeader.get("fromPartyId"));
             input.put("currencyUomId", returnHeader.get("currencyUomId"));
             input.put("invoiceDate", UtilDateTime.nowTimestamp());
-            input.put("description", "Return Invoice for Customer Return #" + returnId); 
+            input.put("description", description); 
             input.put("billingAccountId", returnHeader.get("billingAccountId"));
             input.put("userLogin", userLogin);
 
@@ -1695,24 +1730,47 @@
             // loop through shipment receipts to create invoice items and return item billings for each item and adjustment
             int invoiceItemSeqNum = 1;
             String invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, INVOICE_ITEM_SEQUENCE_ID_DIGITS);
-            for (Iterator iter = receipts.iterator(); iter.hasNext(); ) {
-                GenericValue receipt = (GenericValue) iter.next();
-
+            
+            for (Iterator iter = billItems.iterator(); iter.hasNext(); ) {
+                GenericValue item = (GenericValue) iter.next();
+                boolean shipmentReceiptFound = false;
+                boolean itemIssuanceFound = false;                 
+                if ("ShipmentReceipt".equals(item.getEntityName())) {
+                    shipmentReceiptFound = true;
+                } else if ("ItemIssuance".equals(item.getEntityName())) {
+                    itemIssuanceFound = true;
+                } else {
+                    Debug.logError("Unexpected entity " + item + " of type " + item.getEntityName(), module);
+                }
                 // we need the related return item and product
-                GenericValue returnItem = receipt.getRelatedOneCache("ReturnItem");
+                GenericValue returnItem = null;
+                if (shipmentReceiptFound) {
+                    returnItem = item.getRelatedOneCache("ReturnItem");
+                } else if (itemIssuanceFound) {
+                    GenericValue shipmentItem = item.getRelatedOneCache("ShipmentItem");
+                    GenericValue returnItemShipment = EntityUtil.getFirst(shipmentItem.getRelated("ReturnItemShipment"));
+                    returnItem = returnItemShipment.getRelatedOneCache("ReturnItem");
+                }
+                if (returnItem == null) continue; // Just to prevent NPE
                 GenericValue product = returnItem.getRelatedOneCache("Product");
 
                 // extract the return price as a big decimal for convenience
                 BigDecimal returnPrice = returnItem.getBigDecimal("returnPrice");
 
                 // determine invoice item type from the return item type
-                String invoiceItemTypeId = getInvoiceItemType(delegator, returnItem.getString("returnItemTypeId"), null, "CUST_RTN_INVOICE", null);
+                String invoiceItemTypeId = getInvoiceItemType(delegator, returnItem.getString("returnItemTypeId"), null, invoiceTypeId, null);
                 if (invoiceItemTypeId == null) {
                     return ServiceUtil.returnError(errorMsg + UtilProperties.getMessage(resource, "AccountingNoKnownInvoiceItemTypeReturnItemType",UtilMisc.toMap("returnItemTypeId",returnItem.getString("returnItemTypeId")),locale));
                 }
-
+                double quantity = 0.0;
+                if (shipmentReceiptFound) {
+                    quantity = item.getDouble("quantityAccepted");
+                } else if (itemIssuanceFound) {
+                    quantity = item.getDouble("quantity");
+                }
+                
                 // create the invoice item for this shipment receipt
-                input = UtilMisc.toMap("invoiceId", invoiceId, "invoiceItemTypeId", invoiceItemTypeId, "quantity", receipt.get("quantityAccepted"));
+                input = UtilMisc.toMap("invoiceId", invoiceId, "invoiceItemTypeId", invoiceItemTypeId, "quantity", quantity);
                 input.put("invoiceItemSeqId", "" + invoiceItemSeqId); // turn the int into a string with ("" + int) hack
                 input.put("amount", returnItem.get("returnPrice")); // this service requires Double
                 input.put("productId", returnItem.get("productId"));
@@ -1729,17 +1787,19 @@
                 input = UtilMisc.toMap("returnId", returnId, "returnItemSeqId", returnItem.get("returnItemSeqId"), 
                         "invoiceId", invoiceId);
                 input.put("invoiceItemSeqId", "" + invoiceItemSeqId); // turn the int into a string with ("" + int) hack
-                input.put("shipmentReceiptId", receipt.get("receiptId"));
-                input.put("quantity", receipt.get("quantityAccepted"));
+                input.put("quantity", quantity);
                 input.put("amount", returnItem.get("returnPrice")); // this service requires Double
                 input.put("userLogin", userLogin);
+                if (shipmentReceiptFound) {
+                    input.put("shipmentReceiptId", item.get("receiptId"));
+                }
                 serviceResults = dispatcher.runSync("createReturnItemBilling", input);
                 if (ServiceUtil.isError(serviceResults)) {
                     return ServiceUtil.returnError(errorMsg, null, null, serviceResults);
                 }
                 if (Debug.verboseOn()) {
-                    Debug.logVerbose("Creating Invoice Item with amount " + returnPrice + " and quantity " + receipt.getBigDecimal("quantityAccepted") 
-                            + " for shipment receipt [" + receipt.getString("receiptId") + "]", module);
+                    Debug.logVerbose("Creating Invoice Item with amount " + returnPrice + " and quantity " + quantity 
+                            + " for shipment [" + item.getString("shipmentId") + ":" + item.getString("shipmentItemSeqId") + "]", module);
                 }
 
                 String parentInvoiceItemSeqId = invoiceItemSeqId;                
@@ -1748,8 +1808,15 @@
                 invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, INVOICE_ITEM_SEQUENCE_ID_DIGITS);
 
                 // keep a running total (note: a returnItem may have many receipts. hence, the promised total quantity is the receipt quantityAccepted + quantityRejected)
-                BigDecimal actualAmount = returnPrice.multiply(receipt.getBigDecimal("quantityAccepted")).setScale(decimals, rounding);
-                BigDecimal promisedAmount = returnPrice.multiply(receipt.getBigDecimal("quantityAccepted").add(receipt.getBigDecimal("quantityRejected"))).setScale(decimals, rounding);
+                BigDecimal cancelQuantity = ZERO;
+                if (shipmentReceiptFound) {
+                    cancelQuantity = item.getBigDecimal("quantityRejected");
+                } else if (itemIssuanceFound) {
+                    cancelQuantity = item.getBigDecimal("cancelQuantity");
+                }
+                if (cancelQuantity == null) {cancelQuantity = ZERO;};
+                BigDecimal actualAmount = returnPrice.multiply(BigDecimal.valueOf(quantity)).setScale(decimals, rounding);
+                BigDecimal promisedAmount = returnPrice.multiply(BigDecimal.valueOf(quantity).add(cancelQuantity)).setScale(decimals, rounding);
                 invoiceTotal = invoiceTotal.add(actualAmount).setScale(decimals, rounding);
                 promisedTotal = promisedTotal.add(promisedAmount).setScale(decimals, rounding);
 
@@ -1764,14 +1831,14 @@
                     }
 
                     // determine invoice item type from the return item type
-                    invoiceItemTypeId = getInvoiceItemType(delegator, adjustment.getString("returnAdjustmentTypeId"), null, "CUST_RTN_INVOICE", null);
+                    invoiceItemTypeId = getInvoiceItemType(delegator, adjustment.getString("returnAdjustmentTypeId"), null, invoiceTypeId, null);
                     if (invoiceItemTypeId == null) {
                         return ServiceUtil.returnError(errorMsg + "No known invoice item type for the return adjustment type [" 
                                 +  adjustment.getString("returnAdjustmentTypeId") + "]");
                     }
 
                     // prorate the adjustment amount by the returned amount; do not round ratio
-                    BigDecimal ratio = receipt.getBigDecimal("quantityAccepted").divide(returnItem.getBigDecimal("returnQuantity"), 100, rounding);
+                    BigDecimal ratio = BigDecimal.valueOf(quantity).divide(returnItem.getBigDecimal("returnQuantity"), 100, rounding);
                     BigDecimal amount = adjustment.getBigDecimal("amount");
                     amount = amount.multiply(ratio).setScale(decimals, rounding);
                     if (Debug.verboseOn()) {
@@ -1826,7 +1893,7 @@
                 GenericValue adjustment = (GenericValue) iter.next();
 
                 // determine invoice item type from the return item type
-                String invoiceItemTypeId = getInvoiceItemType(delegator, adjustment.getString("returnAdjustmentTypeId"), null, "CUST_RTN_INVOICE", null);
+                String invoiceItemTypeId = getInvoiceItemType(delegator, adjustment.getString("returnAdjustmentTypeId"), null, invoiceTypeId, null);
                 if (invoiceItemTypeId == null) {
                     return ServiceUtil.returnError(errorMsg + UtilProperties.getMessage(resource, "AccountingNoKnownInvoiceItemTypeReturnAdjustmentType",
                             UtilMisc.toMap("returnAdjustmentTypeId",adjustment.getString("returnAdjustmentTypeId")),locale));

Modified: ofbiz/trunk/applications/order/config/OrderUiLabels.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/config/OrderUiLabels.xml?rev=680690&r1=680689&r2=680690&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/config/OrderUiLabels.xml (original)
+++ ofbiz/trunk/applications/order/config/OrderUiLabels.xml Tue Jul 29 06:28:52 2008
@@ -2432,6 +2432,9 @@
         <value xml:lang="zh_CN">新建退货</value>
         <value xml:lang="zh">创建退货</value>
     </property>
+    <property key="OrderCreateReturnShipment">
+        <value xml:lang="en">Create return shipment</value>
+    </property>        
     <property key="OrderCreateShippingAddress">
         <value xml:lang="en">Create New Shipping Address</value>
         <value xml:lang="fr">Créer une nouvelle adresse d'expédition</value>

Modified: ofbiz/trunk/applications/order/script/org/ofbiz/order/order/OrderReturnServices.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/script/org/ofbiz/order/order/OrderReturnServices.xml?rev=680690&r1=680689&r2=680690&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/script/org/ofbiz/order/order/OrderReturnServices.xml (original)
+++ ofbiz/trunk/applications/order/script/org/ofbiz/order/order/OrderReturnServices.xml Tue Jul 29 06:28:52 2008
@@ -34,26 +34,37 @@
                 <add-error><fail-property resource="OrderErrorUiLabels" property="OrderSecurityErrorToRunCreateReturnHeader"/></add-error>
             </then>
         </if>
-
+        <set field="returnHeaderTypeId" from-field="parameters.returnHeaderTypeId"/>
         <if-empty field="parameters.toPartyId">
-            <!-- no toPartyId was specified.  use destination facility to determine the party of the return -->
-            <if-not-empty field="parameters.destinationFacilityId">
-                <entity-one entity-name="Facility" value-name="destinationFacility" auto-field-map="false">
-                    <field-map field-name="facilityId" env-name="parameters.destinationFacilityId"/>
-                </entity-one>
-                <set from-field="destinationFacility.ownerPartyId" field="parameters.toPartyId"/>
-            </if-not-empty>
+            <!-- no toPartyId was specified. use destination facility to determine the party of the return -->
+            <if-compare field="returnHeaderTypeId" operator="equals" value="CUSTOMER_RETURN">
+                <if-not-empty field="parameters.destinationFacilityId">
+                    <entity-one entity-name="Facility" value-name="destinationFacility" auto-field-map="false">
+                        <field-map field-name="facilityId" env-name="parameters.destinationFacilityId"/>
+                    </entity-one>
+                    <set from-field="destinationFacility.ownerPartyId" field="parameters.toPartyId"/>
+                </if-not-empty>
+            </if-compare>
         <else>
-            <!-- make sure that the party to return to is an INTERNAL_ORGANIZATIO or stop
-            TODO: if we want to implement returns to vendor later, simply change this to make sure that EITHER fromPartyId or toPartyId
-            is an internal organization, and possibly also do a security check on the user -->
-            <entity-one entity-name="PartyRole" value-name="partyRole" use-cache="true" auto-field-map="false">
-                <field-map field-name="partyId" env-name="parameters.toPartyId"/>
-                <field-map field-name="roleTypeId" value="INTERNAL_ORGANIZATIO"/>
-            </entity-one>
-            <if-empty field="partyRole">
-                <add-error><fail-message message="Error: a return must be to a party in the role of internal organization"/></add-error>
-            </if-empty>
+            <!-- make sure that the party to return to is an INTERNAL_ORGANIZATIO for customer return and SUPPLIER for vendor return else stop -->
+            <if-compare field="returnHeaderTypeId" operator="equals" value="CUSTOMER_RETURN">
+                <entity-one entity-name="PartyRole" value-name="partyRole" use-cache="true" auto-field-map="false">
+                    <field-map field-name="partyId" env-name="parameters.toPartyId"/>
+                    <field-map field-name="roleTypeId" value="INTERNAL_ORGANIZATIO"/>
+                </entity-one>
+                <if-empty field="partyRole">
+                    <add-error><fail-message message="Error: a return must be to a party in the role of internal organization"/></add-error>
+                </if-empty>
+            <else>
+                <entity-one entity-name="PartyRole" value-name="partyRole" use-cache="true" auto-field-map="false">
+                    <field-map field-name="partyId" env-name="parameters.toPartyId"/>
+                    <field-map field-name="roleTypeId" value="SUPPLIER"/>
+                </entity-one>
+                <if-empty field="partyRole">
+                    <add-error><fail-message message="Error: a return must be to a party in the role of supplier"/></add-error>
+                </if-empty>            
+            </else>                    
+            </if-compare>    
          </else>
         </if-empty>
         <check-errors/>
@@ -88,7 +99,12 @@
                 <not><if-has-permission permission="ORDERMGR" action="_CREATE"/></not>
             </condition>
             <then>
-                <set field="newEntity.statusId" value="RETURN_REQUESTED"/>
+                <if-compare field="returnHeaderTypeId" operator="equals" value="CUSTOMER_RETURN">
+                    <set field="newEntity.statusId" value="RETURN_REQUESTED"/>
+                <else>
+                    <set field="newEntity.statusId" value="SUP_RETURN_REQUESTED"/>
+                </else>    
+                </if-compare>              
                 <set from-field="nowTimestamp" field="newEntity.entryDate"/>
             </then>
         </if>
@@ -98,7 +114,12 @@
         </if-empty>
 
         <if-empty field="newEntity.statusId">
-            <set value="RETURN_REQUESTED" field="newEntity.statusId"/>
+            <if-compare field="returnHeaderTypeId" operator="equals" value="CUSTOMER_RETURN">
+                <set field="newEntity.statusId" value="RETURN_REQUESTED"/>
+            <else>
+                <set field="newEntity.statusId" value="SUP_RETURN_REQUESTED"/>
+            </else>    
+            </if-compare>     
         </if-empty>
         <set field="newEntity.createdBy" from-field="userLogin.userLoginId"/>
 
@@ -623,31 +644,40 @@
         <entity-one entity-name="OrderHeader" value-name="orderHeader">
             <field-map env-name="parameters.orderId" field-name="orderId"/>
         </entity-one>
-
+        <set field="returnHeaderTypeId" from-field="parameters.returnHeaderTypeId"/>
+        <if-compare field="returnHeaderTypeId" operator="equals" value="CUSTOMER_RETURN">
+            <set field="roleTypeId" value="BILL_TO_CUSTOMER"/>
+        <else>
+            <set field="roleTypeId" value="BILL_FROM_VENDOR"/>
+        </else>    
+        </if-compare>
+        
         <!-- find the bill to customer; for return's fromPartyId -->
         <entity-condition entity-name="OrderRole" list-name="orderRoles">
             <condition-list combine="and">
                 <condition-expr field-name="orderId" operator="equals" env-name="orderHeader.orderId"/>
-                <condition-expr field-name="roleTypeId" operator="equals" value="BILL_TO_CUSTOMER"/>
+                <condition-expr field-name="roleTypeId" operator="equals" env-name="roleTypeId"/>
             </condition-list>
         </entity-condition>
         <first-from-list entry-name="orderRole" list-name="orderRoles"/>
-
         <!-- create the return header -->
         <set from-field="orderHeader.originFacilityId" field="createHeaderCtx.destinationFacilityId"/>
-        <set from-field="orderRole.partyId" field="createHeaderCtx.fromPartyId"/>
         <set value="Y" field="updateHeaderCtx.needsInventoryReceive"/>
-        <set from-field="parameters.returnHeaderTypeId" field="createHeaderCtx.returnHeaderTypeId"/>
-
-        <!-- get the return to party from the product store -->
+        <set from-field="returnHeaderTypeId" field="createHeaderCtx.returnHeaderTypeId"/>
+        
+        <!-- get the return to party for customer return and return from party for vendor return from the product store -->
         <get-related-one relation-name="ProductStore" value-name="orderHeader" to-value-name="productStore"/>
-        <set from-field="productStore.payToPartyId" field="createHeaderCtx.toPartyId"/>
-
-        <if-empty field="createHeaderCtx.destinationFacilityId">
-            <get-related-one value-name="orderHeader" relation-name="ProductStore" to-value-name="productStore"/>
-            <set from-field="productStore.inventoryFacilityId" field="createHeaderCtx.destinationFacilityId"/>
-        </if-empty>
-
+        <if-compare field="returnHeaderTypeId" operator="equals" value="CUSTOMER_RETURN">
+            <set field="createHeaderCtx.fromPartyId" from-field="orderRole.partyId"/>
+            <set field="createHeaderCtx.toPartyId" from-field="productStore.payToPartyId"/>
+            <if-empty field="createHeaderCtx.destinationFacilityId">
+                <set field="createHeaderCtx.destinationFacilityId" from-field="productStore.inventoryFacilityId"/>
+            </if-empty>
+        <else>
+            <set field="createHeaderCtx.fromPartyId" from-field="productStore.payToPartyId"/>
+            <set field="createHeaderCtx.toPartyId" from-field="orderRole.partyId"/>
+        </else>    
+        </if-compare>
         <!-- copy over the currency of the order to the currency of the return -->
         <set from-field="orderHeader.currencyUom" field="createHeaderCtx.currencyUomId"/>
 
@@ -702,14 +732,14 @@
                 </entity-one>
                 <entity-one entity-name="ReturnItemTypeMap" value-name="returnItemTypeMapping">
                     <field-map env-name="product.productTypeId" field-name="returnItemMapKey"/>
-                    <field-map value="CUSTOMER_RETURN" field-name="returnHeaderTypeId"/>
+                    <field-map env-name="returnHeaderTypeId" field-name="returnHeaderTypeId"/>
                 </entity-one>
             <else>
             <!-- if not, try the ReturnItemTypeMap, but this may not actually work, so log a warning -->
                 <log level="warning" message="Trying to find returnItemtype from ReturnItemTypeMap with orderItemtypeId [${orderItem.orderItemTypeId}] for order item [${orderItem}]"/>
                 <entity-one entity-name="ReturnItemTypeMap" value-name="returnItemTypeMapping">
                    <field-map env-name="orderItemTypeId" field-name="returnItemMapKey"/>
-                   <field-map value="CUSTOMER_RETURN" field-name="returnHeaderTypeId"/>
+                   <field-map env-name="returnHeaderTypeId" field-name="returnHeaderTypeId"/>
                 </entity-one>
             </else>
             </if-compare>
@@ -780,20 +810,26 @@
         </if-compare>
 
         <!-- update the header status -->
-        <set value="RETURN_ACCEPTED" field="updateHeaderCtx.statusId"/>
+        <if-compare field="returnHeaderTypeId" operator="equals" value="CUSTOMER_RETURN">
+            <set field="updateHeaderCtx.statusId" value="RETURN_ACCEPTED"/>
+        <else>
+            <set field="updateHeaderCtx.statusId" value="SUP_RETURN_ACCEPTED"/>
+        </else>    
+        </if-compare>    
         <set from-field="returnId" field="updateHeaderCtx.returnId"/>
         <call-service service-name="updateReturnHeader" in-map-name="updateHeaderCtx" include-user-login="true"/>
 
-        <!-- auto-receive this return if we passed in the flag -->
-        <if-compare field="parameters.receiveReturn" operator="equals" value="true" type="Boolean">
-            <set from-field="returnId" field="receiveCtx.returnId"/>
-            <call-service service-name="quickReceiveReturn" in-map-name="receiveCtx"/>
-        <else>
-            <!-- update the header status -->
-            <log level="info" message="Receive flag not set; will handle receiving on entity-sync"/>
-        </else>
+        <if-compare field="returnHeaderTypeId" operator="equals" value="CUSTOMER_RETURN">
+            <!-- auto-receive this return if we passed in the flag -->
+            <if-compare field="parameters.receiveReturn" operator="equals" value="true" type="Boolean">
+                <set from-field="returnId" field="receiveCtx.returnId"/>
+                <call-service service-name="quickReceiveReturn" in-map-name="receiveCtx"/>
+            <else>
+                <!-- update the header status -->
+                <log level="info" message="Receive flag not set; will handle receiving on entity-sync"/>
+            </else>
+            </if-compare>
         </if-compare>
-
         <field-to-result field-name="returnId"/>
     </simple-method>
 
@@ -889,4 +925,19 @@
         <set-nonpk-fields map-name="parameters" value-name="newEntity"/>
         <create-value value-name="newEntity"/>
     </simple-method>
+    
+    <simple-method method-name="getStatusItemsForReturn" short-description="Get the return status associated with customer vs. vendor return">
+        <if-compare field="parameters.returnHeaderTypeId" operator="equals" value="CUSTOMER_RETURN">
+            <entity-and entity-name="StatusItem" list-name="statusItems">
+                <field-map field-name="statusTypeId" value="ORDER_RETURN_STTS"/>
+            </entity-and>
+            <field-to-result field-name="statusItems"/>
+        <else>
+            <entity-and entity-name="StatusItem" list-name="statusItems">
+                <field-map field-name="statusTypeId" value="PORDER_RETURN_STTS"/>
+            </entity-and>
+            <field-to-result field-name="statusItems"/>
+        </else>
+        </if-compare>
+    </simple-method>    
 </simple-methods>

Modified: ofbiz/trunk/applications/order/servicedef/secas.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/servicedef/secas.xml?rev=680690&r1=680689&r2=680690&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/servicedef/secas.xml (original)
+++ ofbiz/trunk/applications/order/servicedef/secas.xml Tue Jul 29 06:28:52 2008
@@ -202,6 +202,11 @@
         <action service="cancelReturnItems" mode="sync"/>
         <action service="sendReturnCancelNotification" mode="async" persist="true"/>
     </eca>
+    <eca service="updateReturnHeader" event="commit">
+        <condition field-name="statusId" operator="equals" value="SUP_RETURN_SHIPPED"/>
+        <condition field-name="currentStatusId" operator="not-equals" value="SUP_RETURN_SHIPPED"/>
+        <action service="processWaitReplacementReturn" mode="sync"/>
+    </eca>
 
     <eca service="updateReturnItem" event="commit">
         <condition field-name="statusId" operator="equals" value="RETURN_CANCELLED"/>

Modified: ofbiz/trunk/applications/order/servicedef/services_return.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/servicedef/services_return.xml?rev=680690&r1=680689&r2=680690&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/servicedef/services_return.xml (original)
+++ ofbiz/trunk/applications/order/servicedef/services_return.xml Tue Jul 29 06:28:52 2008
@@ -294,4 +294,11 @@
         <description>Create a new ReturnItemShipment</description>
         <auto-attributes entity-name="ReturnItemShipment" include="all" mode="IN" optional="false"/>
     </service>
+    
+    <service name="getStatusItemsForReturn" engine="simple"
+            location="org/ofbiz/order/order/OrderReturnServices.xml" invoke="getStatusItemsForReturn">
+        <description>Get the return status associated with customer/vendor return</description>
+        <attribute name="returnHeaderTypeId" type="String" mode="IN" optional="false"/>
+        <attribute name="statusItems" type="List" mode="OUT" optional="false"/>
+    </service>    
 </services>

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=680690&r1=680689&r2=680690&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 Tue Jul 29 06:28:52 2008
@@ -1348,7 +1348,7 @@
             Debug.logError(e, "Problems looking up return information", module);
             return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorGettingReturnHeaderItemInformation", locale));
         }
-
+        String returnHeaderTypeId = returnHeader.getString("returnHeaderTypeId");
         List createdOrderIds = new ArrayList();
         if (returnHeader != null && returnItems != null && returnItems.size() > 0) {
             Map returnItemsByOrderId = new HashMap();
@@ -1376,13 +1376,22 @@
 
                 // create the replacement order
                 Map orderMap = UtilMisc.toMap("userLogin", userLogin);
-                GenericValue placingParty = orh.getPlacingParty();
+                
                 String placingPartyId = null;
-                if (placingParty != null) {
-                    placingPartyId = placingParty.getString("partyId");
+                GenericValue placingParty = null;
+                if ("CUSTOMER_RETURN".equals(returnHeaderTypeId)) {
+                    placingParty = orh.getPlacingParty();
+                    if (placingParty != null) {
+                        placingPartyId = placingParty.getString("partyId");
+                    }                    
+                    orderMap.put("orderTypeId", "SALES_ORDER");
+                } else {
+                    placingParty = orh.getSupplierAgent();
+                    if (placingParty != null) {
+                        placingPartyId = placingParty.getString("partyId");
+                    }                      
+                    orderMap.put("orderTypeId", "PURCHASE_ORDER");
                 }
-
-                orderMap.put("orderTypeId", "SALES_ORDER");
                 orderMap.put("partyId", placingPartyId);
                 orderMap.put("productStoreId", orderHeader.get("productStoreId"));
                 orderMap.put("webSiteId", orderHeader.get("webSiteId"));
@@ -1456,40 +1465,41 @@
                                 // Check if the product being returned has a Refurbished Equivalent and if so
                                 // (and there is inventory for the assoc product) use that product instead
                                 GenericValue refurbItem = null;
-                                try {
-                                    if (UtilValidate.isNotEmpty(product)) {
-                                        GenericValue refurbItemAssoc = EntityUtil.getFirst(EntityUtil.filterByDate(product.getRelated("MainProductAssoc",
-                                                                                                   UtilMisc.toMap("productAssocTypeId", "PRODUCT_REFURB"),
-                                                                                                   UtilMisc.toList("sequenceNum"))));
-                                        if (UtilValidate.isNotEmpty(refurbItemAssoc)) {
-                                            refurbItem = refurbItemAssoc.getRelatedOne("AssocProduct");
-                                        }
-                                    }
-                                } catch (GenericEntityException e) {
-                                    Debug.logError(e, module);
-                                }
-                                if (UtilValidate.isNotEmpty(refurbItem)) {
-                                    boolean inventoryAvailable = false;
+                                if ("CUSTOMER_RETURN".equals(returnHeaderTypeId)) {
                                     try {
-                                        Map invReqResult = dispatcher.runSync("isStoreInventoryAvailable", UtilMisc.toMap("productStoreId", orderHeader.get("productStoreId"),
-                                                                                                                                       "productId", refurbItem.getString("productId"),
-                                                                                                                                       "product", refurbItem, "quantity", quantity));
-                                        if (ServiceUtil.isError(invReqResult)) {
-                                            Debug.logError("Error calling isStoreInventoryAvailable service, result is: " + invReqResult, module);
-                                        } else {
-                                            inventoryAvailable = "Y".equals((String) invReqResult.get("available"));
+                                        if (UtilValidate.isNotEmpty(product)) {
+                                            GenericValue refurbItemAssoc = EntityUtil.getFirst(EntityUtil.filterByDate(product.getRelated("MainProductAssoc",
+                                                                                                       UtilMisc.toMap("productAssocTypeId", "PRODUCT_REFURB"),
+                                                                                                       UtilMisc.toList("sequenceNum"))));
+                                            if (UtilValidate.isNotEmpty(refurbItemAssoc)) {
+                                                refurbItem = refurbItemAssoc.getRelatedOne("AssocProduct");
+                                            }
                                         }
-                                    } catch (GenericServiceException e) {
-                                        Debug.logError(e, "Fatal error calling inventory checking services: " + e.toString(), module);
+                                    } catch (GenericEntityException e) {
+                                        Debug.logError(e, module);
                                     }
-                                    if (!inventoryAvailable) {
-                                        // If the Refurbished Equivalent is not available,
-                                        // then use the original product.
-                                        refurbItem = null;
+                                    if (UtilValidate.isNotEmpty(refurbItem)) {
+                                        boolean inventoryAvailable = false;
+                                        try {
+                                            Map invReqResult = dispatcher.runSync("isStoreInventoryAvailable", UtilMisc.toMap("productStoreId", orderHeader.get("productStoreId"),
+                                                                                                                                           "productId", refurbItem.getString("productId"),
+                                                                                                                                           "product", refurbItem, "quantity", quantity));
+                                            if (ServiceUtil.isError(invReqResult)) {
+                                                Debug.logError("Error calling isStoreInventoryAvailable service, result is: " + invReqResult, module);
+                                            } else {
+                                                inventoryAvailable = "Y".equals((String) invReqResult.get("available"));
+                                            }
+                                        } catch (GenericServiceException e) {
+                                            Debug.logError(e, "Fatal error calling inventory checking services: " + e.toString(), module);
+                                        }
+                                        if (!inventoryAvailable) {
+                                            // If the Refurbished Equivalent is not available,
+                                            // then use the original product.
+                                            refurbItem = null;
+                                        }
                                     }
                                 }
                                 
-                                
                                 GenericValue newItem = delegator.makeValue("OrderItem", UtilMisc.toMap("orderItemSeqId", UtilFormatOut.formatPaddedNumber(itemCount++, 5)));
                                 if (UtilValidate.isEmpty(refurbItem)) {
                                     newItem.set("productId", orderItem.get("productId"));

Modified: ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/return/QuickReturn.groovy
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/return/QuickReturn.groovy?rev=680690&r1=680689&r2=680690&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/return/QuickReturn.groovy (original)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/return/QuickReturn.groovy Tue Jul 29 06:28:52 2008
@@ -27,10 +27,15 @@
 orderId = parameters.orderId;
 context.orderId = orderId;
 
+returnHeaderTypeId = parameters.returnHeaderTypeId;
+context.returnHeaderTypeId = returnHeaderTypeId;
+
 partyId = parameters.party_id;
-context.partyId = partyId;
 
 if (partyId) {
+    if (("VENDOR_RETURN").equals(returnHeaderTypeId)) {
+        context.toPartyId = partyId;
+    }
     party = delegator.findByPrimaryKey("Party", [partyId : partyId]);
     context.party = party;
 }
@@ -43,12 +48,17 @@
     order = delegator.findByPrimaryKey("OrderHeader", [orderId : orderId]);
     productStore = order.getRelatedOne("ProductStore");
     if (productStore) {
-        context.destinationFacilityId = ProductStoreWorker.determineSingleFacilityForStore(delegator, productStore.productStoreId);
+        if (("VENDOR_RETURN").equals(returnHeaderTypeId)) {
+            context.partyId = productStore.payToPartyId;
+        } else {
+            context.destinationFacilityId = ProductStoreWorker.determineSingleFacilityForStore(delegator, productStore.productStoreId);
+            context.toPartyId = productStore.payToPartyId;
+            context.partyId = partyId;            
+        }
     }
 
     orh = new OrderReadHelper(order);
     context.orh = orh;
-    context.toPartyId = productStore.payToPartyId;
     context.orderHeaderAdjustments = orh.getAvailableOrderHeaderAdjustments();
 }
 
@@ -75,7 +85,7 @@
 context.itemStts = itemStts;
 
 typeMap = [:];
-returnItemTypeMap = delegator.findByAnd("ReturnItemTypeMap", [returnHeaderTypeId : "CUSTOMER_RETURN"]);
+returnItemTypeMap = delegator.findByAnd("ReturnItemTypeMap", [returnHeaderTypeId : returnHeaderTypeId]);
 returnItemTypeMap.each { value ->
     typeMap[value.returnItemMapKey] = value.returnItemTypeId;
 }

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=680690&r1=680689&r2=680690&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 Tue Jul 29 06:28:52 2008
@@ -75,6 +75,8 @@
 
 if (returnHeader) {
     contactMechTo = ContactMechWorker.getFacilityContactMechByPurpose(delegator, returnHeader.destinationFacilityId, ["PUR_RET_LOCATION", "SHIPPING_LOCATION", "PRIMARY_LOCATION"]);
-    postalAddressTo = delegator.findOne("PostalAddress", [contactMechId : contactMechTo.contactMechId], true);
-    context.postalAddressTo = postalAddressTo;
+    if (contactMechTo) {
+        postalAddressTo = delegator.findOne("PostalAddress", [contactMechId : contactMechTo.contactMechId], true);
+        context.postalAddressTo = postalAddressTo;
+    }    
 }

Modified: ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnItems.groovy
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnItems.groovy?rev=680690&r1=680689&r2=680690&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnItems.groovy (original)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnItems.groovy Tue Jul 29 06:28:52 2008
@@ -34,6 +34,9 @@
 returnHeader = delegator.findByPrimaryKey("ReturnHeader", [returnId : returnId]);
 context.returnHeader = returnHeader;
 
+returnHeaderTypeId = returnHeader.returnHeaderTypeId;
+context.toPartyId = returnHeader.toPartyId;
+
 returnItems = delegator.findByAnd("ReturnItem", [returnId : returnId]);
 context.returnItems = returnItems;
 
@@ -53,7 +56,7 @@
 itemStts = delegator.findByAnd("StatusItem", [statusTypeId : "INV_SERIALIZED_STTS"], ["sequenceId"]);
 context.itemStts = itemStts;
 
-returnItemTypeMap = delegator.findByAnd("ReturnItemTypeMap", [returnHeaderTypeId : "CUSTOMER_RETURN"]);
+returnItemTypeMap = delegator.findByAnd("ReturnItemTypeMap", [returnHeaderTypeId : returnHeaderTypeId]);
 typeMap = [:];
 returnItemTypeMap.each { value ->
     typeMap[value.returnItemMapKey] = value.returnItemTypeId;
@@ -74,8 +77,11 @@
     shippingAmount = shipRes.shippingAmount;
     context.shippingAmount = shippingAmount;
 }
-
-partyOrders = delegator.findByAnd("OrderHeaderAndRoles", [roleTypeId : "PLACING_CUSTOMER", partyId : returnHeader.fromPartyId], ["orderId"]);
+roleTypeId = "PLACING_CUSTOMER";
+if (returnHeaderTypeId == "VENDOR_RETURN") {
+    roleTypeId = "SUPPLIER";
+}
+partyOrders = delegator.findByAnd("OrderHeaderAndRoles", [roleTypeId : roleTypeId, partyId : returnHeader.fromPartyId], ["orderId"]);
 context.partyOrders = partyOrders;
 
 // get the list of return shipments associated to the return

Modified: ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/controller.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/controller.xml?rev=680690&r1=680689&r2=680690&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/controller.xml (original)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/controller.xml Tue Jul 29 06:28:52 2008
@@ -943,6 +943,12 @@
         <response name="success" type="view" value="returnitems"/>
     </request-map>
     
+    <request-map uri="getStatusItemsForReturn">
+        <security https="true" auth="true"/>
+        <event type="jsonservice" invoke="getStatusItemsForReturn"/>
+        <response name="success" type="none"/>
+        <response name="error" type="none"/>
+    </request-map>    
     
     <!-- Payment Processor Setup Requests -->
     <request-map uri="paysetup">

Added: ofbiz/trunk/applications/order/webapp/ordermgr/images/js/return.js
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/images/js/return.js?rev=680690&view=auto
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/images/js/return.js (added)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/images/js/return.js Tue Jul 29 06:28:52 2008
@@ -0,0 +1,39 @@
+/*
+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.
+*/
+
+Event.observe(window, 'load', function() {
+    Event.observe($('returnHeaderTypeId'), 'change', function() {
+        changeStatusCorrespondingToHeaderType();
+    });
+});
+
+function changeStatusCorrespondingToHeaderType() {
+    var listOptions = [];
+    new Ajax.Request('/ordermgr/control/getStatusItemsForReturn', {
+        asynchronous: false, 
+        onSuccess: function(transport) {
+            var data = transport.responseText.evalJSON(true);
+            var statusItems = data.statusItems;
+            statusItems.each( function(statusItem) {
+                listOptions.push("<option value = " + statusItem.statusId + " > " + statusItem.description + " </option>");
+            });
+            $('statusId').update(listOptions);            
+        }, parameters: {returnHeaderTypeId: $F('returnHeaderTypeId')}, requestHeaders: {Accept: 'application/json'}
+    });    
+}
\ No newline at end of file

Propchange: ofbiz/trunk/applications/order/webapp/ordermgr/images/js/return.js
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/applications/order/webapp/ordermgr/images/js/return.js
------------------------------------------------------------------------------
    svn:keywords = Date Rev Author URL Id

Propchange: ofbiz/trunk/applications/order/webapp/ordermgr/images/js/return.js
------------------------------------------------------------------------------
    svn:mime-type = text/plain

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=680690&r1=680689&r2=680690&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/return/ReturnForms.xml (original)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/return/ReturnForms.xml Tue Jul 29 06:28:52 2008
@@ -20,7 +20,7 @@
 
 <forms xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/widget-form.xsd">
-    <form name="EditReturn" type="single" target="updateReturn" default-map-name="returnHeader"
+    <form name="EditReturn" type="single" target="updateReturn" default-map-name="returnHeader" id="editReturn"
         header-row-style="header-row" default-table-style="basic-table">
         <actions>
             <entity-one entity-name="StatusItem" value-name="currentStatus" auto-field-map="false">
@@ -33,12 +33,12 @@
         <field use-when="returnHeader==null&amp;&amp;returnId!=null" name="returnId" tooltip="Could not find Return with ID [${returnId}]"><text size="20" maxlength="20"/></field>
         <field use-when="returnHeader==null&amp;&amp;returnId==null" name="returnId"><ignored/></field>
         <field name="currentStatusId" entry-name="statusId"><hidden/></field>
-        <field name="returnHeaderTypeId">
+        <field name="returnHeaderTypeId" id-name="returnHeaderTypeId">
             <drop-down allow-empty="false">
                 <entity-options entity-name="ReturnHeaderType" description="${description}"/>
             </drop-down>
         </field>
-        <field name="statusId" use-when="returnHeader==null">
+        <field name="statusId" use-when="returnHeader==null" id-name="statusId">
             <drop-down>
                 <entity-options entity-name="StatusItem" description="${description}">
                     <entity-constraint name="statusTypeId" value="ORDER_RETURN_STTS"/>

Modified: ofbiz/trunk/applications/order/webapp/ordermgr/return/quickReturn.ftl
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/return/quickReturn.ftl?rev=680690&r1=680689&r2=680690&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/return/quickReturn.ftl (original)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/return/quickReturn.ftl Tue Jul 29 06:28:52 2008
@@ -27,17 +27,18 @@
         <form name="selectAllForm" method="post" action="<@o...@ofbizUrl>">
           <input type="hidden" name="_checkGlobalScope" value="Y"/>
           <input type="hidden" name="_useRowSubmit" value="Y"/>
-          <input type="hidden" name="fromPartyId" value="${party.partyId}"/>
+          <input type="hidden" name="fromPartyId" value="${partyId?if_exists}"/>
           <input type="hidden" name="toPartyId" value="${toPartyId?if_exists}"/>
           <input type="hidden" name="orderId" value="${orderId}"/>
           <input type="hidden" name="needsInventoryReceive" value="${parameters.needsInventoryReceive?default("Y")}"/>
-          <input type="hidden" name="destinationFacilityId" value="${destinationFacilityId}"/>
-          <input type="hidden" name="returnHeaderTypeId" value="CUSTOMER_RETURN"/>
+          <input type="hidden" name="destinationFacilityId" value="${destinationFacilityId?if_exists}"/>
+          <input type="hidden" name="returnHeaderTypeId" value="${returnHeaderTypeId}"/>
           <#if (orderHeader?has_content) && (orderHeader.currencyUom?has_content)>
           <input type="hidden" name="currencyUomId" value="${orderHeader.currencyUom}"/>
           </#if>
           <#include "returnItemInc.ftl"/>
           <hr/>
+          <#if "CUSTOMER_RETURN" == returnHeaderTypeId>
           <h3>${uiLabelMap.FormFieldTitle_paymentMethodId}:</h3>
           <table cellspacing="0" class="basic-table">
             <tr><td>
@@ -64,10 +65,11 @@
               </#if>
             </td></tr>
           </table>
+          </#if>
           <table cellspacing="0" class="basic-table">
             <tr><td colspan="8"><hr></td></tr>
             <tr>
-              <td colspan="8"><h3>${uiLabelMap.OrderReturnShipFromAddress}</h3></td>
+              <td colspan="8"><h3><#if "CUSTOMER_RETURN" == returnHeaderTypeId>${uiLabelMap.OrderReturnShipFromAddress}<#else>${uiLabelMap["checkhelper.select_shipping_destination"]}</#if></h3></td>
             </tr>
             <tr>
               <td colspan="8">

Modified: ofbiz/trunk/applications/order/webapp/ordermgr/return/returnItems.ftl
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/return/returnItems.ftl?rev=680690&r1=680689&r2=680690&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/return/returnItems.ftl (original)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/return/returnItems.ftl Tue Jul 29 06:28:52 2008
@@ -65,12 +65,21 @@
     </tr>    
 </#macro>
 
-
-    <#if returnHeader?has_content && returnHeader.destinationFacilityId?has_content && returnHeader.statusId == "RETURN_ACCEPTED">
-      <#list returnShipmentIds as returnShipmentId>
-        <a href="/facility/control/ViewShipment?shipmentId=${returnShipmentId.shipmentId}${externalKeyParam}" class="buttontext">${uiLabelMap.ProductShipmentId} ${returnShipmentId.shipmentId}</a>
-        <a href="/facility/control/ReceiveReturn?facilityId=${returnHeader.destinationFacilityId}&returnId=${returnHeader.returnId?if_exists}&shipmentId=${returnShipmentId.shipmentId}${externalKeyParam}" class="buttontext">${uiLabelMap.OrderReceiveReturn}</a>
-      </#list>
+    <#if returnHeader?has_content>
+      <#if returnHeader.destinationFacilityId?has_content && returnHeader.statusId == "RETURN_ACCEPTED" && returnHeader.returnHeaderTypeId == "CUSTOMER_RETURN">
+        <#list returnShipmentIds as returnShipmentId>
+          <a href="/facility/control/ViewShipment?shipmentId=${returnShipmentId.shipmentId}${externalKeyParam}" class="buttontext">${uiLabelMap.ProductShipmentId} ${returnShipmentId.shipmentId}</a>
+          <a href="/facility/control/ReceiveReturn?facilityId=${returnHeader.destinationFacilityId}&returnId=${returnHeader.returnId?if_exists}&shipmentId=${returnShipmentId.shipmentId}${externalKeyParam}" class="buttontext">${uiLabelMap.OrderReceiveReturn}</a>
+        </#list>
+      <#elseif returnHeader.statusId == "SUP_RETURN_ACCEPTED" && returnHeader.returnHeaderTypeId == "VENDOR_RETURN">
+         <#if returnShipmentIds?has_content>
+           <#list returnShipmentIds as returnShipmentId>
+             <a href="/facility/control/ViewShipment?shipmentId=${returnShipmentId.shipmentId}${externalKeyParam}" class="buttontext">${uiLabelMap.ProductShipmentId} ${returnShipmentId.shipmentId}</a>
+           </#list>         
+         <#else> 
+           <a href="/facility/control/EditShipment?primaryReturnId=${returnHeader.returnId}&partyIdTo=${toPartyId}&statusId=SHIPMENT_INPUT&shipmentTypeId=PURCHASE_RETURN" class="buttontext">${uiLabelMap.OrderCreateReturnShipment}</a>
+         </#if>  
+      </#if> 
     </#if>
 
 <div class="screenlet">

Modified: ofbiz/trunk/applications/order/widget/ordermgr/OrderReturnScreens.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/widget/ordermgr/OrderReturnScreens.xml?rev=680690&r1=680689&r2=680690&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/widget/ordermgr/OrderReturnScreens.xml (original)
+++ ofbiz/trunk/applications/order/widget/ordermgr/OrderReturnScreens.xml Tue Jul 29 06:28:52 2008
@@ -110,7 +110,8 @@
             <actions>
                 <set field="titleProperty" value="PageTitleReturnHeader"/>
                 <set field="headerItem" value="return"/>
-                <set field="tabButtonItem" value="OrderReturnHeader"/>                
+                <set field="tabButtonItem" value="OrderReturnHeader"/>
+                <set field="layoutSettings.javaScripts[+0]" value="/ordermgr/images/js/return.js" global="true"/>
                 <property-to-field field="defaultCurrencyUomId" resource="general" property="currency.uom.id.default" default="USD"/>
                 <script location="component://order/webapp/ordermgr/WEB-INF/actions/return/ReturnHeader.groovy"/>
             </actions>

Modified: ofbiz/trunk/applications/product/config/ProductUiLabels.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/config/ProductUiLabels.xml?rev=680690&r1=680689&r2=680690&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/config/ProductUiLabels.xml (original)
+++ ofbiz/trunk/applications/product/config/ProductUiLabels.xml Tue Jul 29 06:28:52 2008
@@ -5869,6 +5869,9 @@
         <value xml:lang="it">Markup Percentuale</value>
         <value xml:lang="th">เพิ่มราคาอัตราร้อยละ</value>
     </property>
+    <property key="ProductAddItemsFromInventory">
+        <value xml:lang="en">Add Items From Inventory</value>
+    </property>        
     <property key="ProductCrossSell">
         <value xml:lang="en">You might be interested in these as well:</value>
         <value xml:lang="fr">Vous pourriez aussi être intéressé(e) par ceci :</value>
@@ -10602,6 +10605,9 @@
         <value xml:lang="th">จำนวนทั้งหมด</value>
         <value xml:lang="zh">全部交付</value>
     </property>
+    <property key="ProductIssueInventoryItemsToShipment">
+        <value xml:lang="en">Issue Inventory Item(s) to Shipment</value>
+    </property>        
     <property key="ProductIssuedQuantity">
         <value xml:lang="en">Issued Quantity</value>
         <value xml:lang="es">Cantidad publicada</value>
@@ -11076,6 +11082,9 @@
         <value xml:lang="th">คำอธิบาย</value>
         <value xml:lang="zh">详细描述</value>
     </property>
+    <property key="ProductLookupInventory">
+        <value xml:lang="en">Lookup Inventory(s)</value>
+    </property>        
     <property key="ProductLookupShipment">
         <value xml:lang="en">Lookup Shipment(s)</value>
         <value xml:lang="es">Buscar envío(s)</value>
@@ -13465,6 +13474,9 @@
         <value xml:lang="th">กลุ่มในขั้นพื้นฐาน</value>
         <value xml:lang="zh">主要上级组</value>
     </property>
+    <property key="ProductPrimaryReturnId">
+        <value xml:lang="en">Primary Return ID</value>
+    </property>        
     <property key="ProductPrimaryShipGroupSeqId">
         <value xml:lang="en">Primary Ship Group Seq Id</value>
         <value xml:lang="es">Código de secuencia del grupo primario de envío</value>
@@ -15943,6 +15955,9 @@
         <value xml:lang="th">แผนการขนส่ง --> รายการการสั่งซื้อ</value>
         <value xml:lang="zh">货运计划 --> 订单明细</value>
     </property>
+    <property key="ProductShipmentQty">
+        <value xml:lang="en">Shipment Qty</value>
+    </property>        
     <property key="ProductShipmentQuickComplete">
         <value xml:lang="en">Quick Complete Drop Shipment</value>
         <value xml:lang="fr">Rapide livraison complète par un tiers</value>

Modified: ofbiz/trunk/applications/product/entitydef/entitymodel_shipment.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/entitydef/entitymodel_shipment.xml?rev=680690&r1=680689&r2=680690&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/entitydef/entitymodel_shipment.xml (original)
+++ ofbiz/trunk/applications/product/entitydef/entitymodel_shipment.xml Tue Jul 29 06:28:52 2008
@@ -525,6 +525,7 @@
       <field name="shipmentTypeId" type="id"></field>
       <field name="statusId" type="id-ne"></field>
       <field name="primaryOrderId" type="id"></field>
+      <field name="primaryReturnId" type="id"></field>
       <field name="primaryShipGroupSeqId" type="id"></field>
       <field name="picklistBinId" type="id"></field>
       <field name="estimatedReadyDate" type="date-time"></field>
@@ -593,6 +594,9 @@
       <relation type="one" fk-name="SHPMNT_PODR" title="Primary" rel-entity-name="OrderHeader">
         <key-map field-name="primaryOrderId" rel-field-name="orderId"/>
       </relation>
+      <relation type="one" fk-name="SHPMNT_PRTNHDR" title="Primary" rel-entity-name="ReturnHeader">
+        <key-map field-name="primaryReturnId" rel-field-name="returnId"/>
+      </relation>      
       <relation type="one" rel-entity-name="PicklistBin">
           <key-map field-name="picklistBinId"/>
       </relation>

Modified: ofbiz/trunk/applications/product/script/org/ofbiz/product/inventory/InventoryServices.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/script/org/ofbiz/product/inventory/InventoryServices.xml?rev=680690&r1=680689&r2=680690&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/script/org/ofbiz/product/inventory/InventoryServices.xml (original)
+++ ofbiz/trunk/applications/product/script/org/ofbiz/product/inventory/InventoryServices.xml Tue Jul 29 06:28:52 2008
@@ -1247,7 +1247,45 @@
         <entity-one entity-name="InventoryItemLabelAppl" value-name="lookedUpValue"/>
         <remove-value value-name="lookedUpValue"/>
     </simple-method>
-    
+ 
+     <simple-method method-name="getInventoryItemForAssociatedOrderSupplierAndProduct" short-description="Get Inventory Items for an order, supplier and product">
+       <set field="productId" from-field="parameters.productId"/>
+       <!-- search for the original inventory items created by order -->
+       <entity-and entity-name="ShipmentReceipt" list-name="shipmentReceipts">
+           <field-map field-name="orderId" env-name="parameters.orderId"/>
+           <field-map field-name="productId" env-name="productId"/>
+       </entity-and>
+       <if-not-empty field="shipmentReceipts">
+           <first-from-list list-name="shipmentReceipts" entry-name="shipmentReceipt"/>
+           <get-related value-name="shipmentReceipt" relation-name="InventoryItem" list-name="inventoryItems"/>
+           <field-to-result field-name="inventoryItems"/>
+           <return/>       
+       </if-not-empty>
+       <!-- search for inventory items created by other orders from the same supplier -->
+       <entity-and entity-name="OrderRole" list-name="orderRoles">
+           <field-map field-name="partyId" env-name="parameters.partyId"/>
+       </entity-and>
+       <iterate list-name="orderRoles" entry-name="orderRole">
+           <entity-and entity-name="ShipmentReceipt" list-name="shipmentReceipts">
+               <field-map field-name="orderId" env-name="orderRole.orderId"/>
+               <field-map field-name="productId" env-name="productId"/>
+           </entity-and>
+           <first-from-list list-name="shipmentReceipts" entry-name="shipmentReceipt"/>
+           <get-related value-name="shipmentReceipt" relation-name="InventoryItem" list-name="inventoryItems"/>
+           <field-to-list field-name="inventoryItems" list-name="inventoryItems"/>           
+       </iterate>
+       <if-not-empty field="inventoryItems">
+           <field-to-result field-name="inventoryItems"/>
+           <return/>       
+       </if-not-empty>
+       <clear-field field-name="inventoryItems"/>
+       <!-- search for all the inventory items for this product -->
+       <entity-and entity-name="InventoryItem" list-name="inventoryItems">
+           <field-map field-name="productId" env-name="productId"/>
+       </entity-and>
+       <field-to-result field-name="inventoryItems"/>
+     </simple-method>
+      
     <!-- Test Physical Inventory Adjustment -->
     <simple-method method-name="testPhysicalInventoryAdjustment" short-description="Test to create physical inventory and variance" login-required="false">
         <log level="info" message="====================Create physical inventory and variance test case================================"/>

Modified: ofbiz/trunk/applications/product/script/org/ofbiz/shipment/issuance/IssuanceServices.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/script/org/ofbiz/shipment/issuance/IssuanceServices.xml?rev=680690&r1=680689&r2=680690&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/script/org/ofbiz/shipment/issuance/IssuanceServices.xml (original)
+++ ofbiz/trunk/applications/product/script/org/ofbiz/shipment/issuance/IssuanceServices.xml Tue Jul 29 06:28:52 2008
@@ -530,4 +530,55 @@
         <field-to-result field-name="toCancelQuantity" result-name="canceledQuantity"/>
     </simple-method>    
     
+    <simple-method method-name="issueInventoryItemToShipment" short-description="Issue InventoryItem To Shipment">
+        <set field="shipmentId" from-field="parameters.shipmentId"/>
+        <set field="shipmentItemSeqId" from-field="parameters.shipmentItemSeqId"/>
+        <entity-one entity-name="InventoryItem" value-name="inventoryItem"/>
+        <entity-and entity-name="ReturnItemShipment" list-name="returnItemShipments">
+          <field-map field-name="shipmentId" env-name="parameters.shipmentId"/>
+          <field-map field-name="shipmentItemSeqId" env-name="parameters.shipmentItemSeqId"/>
+        </entity-and>
+        <first-from-list list-name="returnItemShipments" entry-name="returnItemShipment"/>
+        <calculate field-name="quantityNotIssued">
+          <calcop operator="subtract" field-name="returnItemShipment.quantity">
+              <calcop operator="get" field-name="parameters.totalIssuedQty"/>
+          </calcop>
+        </calculate>
+        <!-- make sure specified quantity is not less than or equal to 0 -->
+        <if-compare field="parameters.quantity" operator="less-equals" value="0" type="Double">
+            <add-error><fail-message message="Not issuing InventoryItem to Shipment [${parameters.shipmentId}:$${parameters.shipmentItemSeqId}] because the quantity to issue [${parameters.quantity}] is less than or equal to 0 for inventoryItem [${inventoryItem.inventoryItemId}]"/></add-error>
+        </if-compare>
+        <!-- make sure specified quantity is not greater than available quantity left to be issued, i.e. intentoryItem.availableToPromiseTotal -->
+        <if-compare-field field="parameters.quantity" to-field="inventoryItem.availableToPromiseTotal" operator="greater" type="Double">
+            <add-error><fail-message message="Not issuing InventoryItem to Shipment [${parameters.shipmentId}:${parameters.shipmentItemSeqId}] because the quantity to issue [${parameters.quantity}] is greater than the quantity left to issue (ie the ATP or Available To Promise) [${intentoryItem.availableToPromiseTotal}] for inventoryItem [${parameters.inventoryItemId}]"/></add-error>
+        </if-compare-field>
+        <!-- make sure specified quantity is not greater than total return quantity -->
+        <if-compare-field field="parameters.quantity" to-field="quantityNotIssued" operator="greater" type="Double">
+            <add-error><fail-message message="Not issuing InventoryItem to Shipment [${parameters.shipmentId}:${parameters.shipmentItemSeqId}] because the quantity to issue [${parameters.quantity}] is greater than the quantity left to return for inventoryItem [${parameters.inventoryItemId}]"/></add-error>
+        </if-compare-field>        
+        <check-errors/>
+        
+        <!-- create the ItemIssuance -->
+        <set field="itemIssuanceCreate.quantity" from-field="parameters.quantity"/>
+        <set field="itemIssuanceCreate.inventoryItemId" from-field="parameters.inventoryItemId"/>
+        <set field="itemIssuanceCreate.shipmentId" from-field="shipmentId"/>
+        <set field="itemIssuanceCreate.shipmentItemSeqId" from-field="shipmentItemSeqId"/>
+        <set field="itemIssuanceCreate.issuedByUserLoginId" from-field="userLogin.userLoginId" />
+        <call-service service-name="createItemIssuance" in-map-name="itemIssuanceCreate">
+            <result-to-field result-name="itemIssuanceId"/>
+        </call-service>
+        <field-to-result field-name="itemIssuanceId"/>
+
+        <set field="createDetailMap.inventoryItemId" from-field="inventoryItem.inventoryItemId"/>
+        <set field="createDetailMap.itemIssuanceId" from-field="itemIssuanceId"/>
+        <set field="createDetailMap.shipmentId" from-field="shipmentId"/>
+        <set field="createDetailMap.shipmentItemSeqId" from-field="shipmentItemSeqId"/>
+        <calculate field-name="createDetailMap.quantityOnHandDiff" type="Double">
+            <calcop field-name="parameters.quantity" operator="negative"/>
+        </calculate>
+        <calculate field-name="createDetailMap.availableToPromiseDiff" type="Double">
+            <calcop field-name="parameters.quantity" operator="negative"/>
+        </calculate>
+        <call-service service-name="createInventoryItemDetail" in-map-name="createDetailMap"/>
+    </simple-method>    
 </simple-methods>

Modified: ofbiz/trunk/applications/product/script/org/ofbiz/shipment/shipment/ShipmentServices.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/script/org/ofbiz/shipment/shipment/ShipmentServices.xml?rev=680690&r1=680689&r2=680690&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/script/org/ofbiz/shipment/shipment/ShipmentServices.xml (original)
+++ ofbiz/trunk/applications/product/script/org/ofbiz/shipment/shipment/ShipmentServices.xml Tue Jul 29 06:28:52 2008
@@ -260,18 +260,33 @@
         <set from-field="returnHeader.toPartyId" field="shipmentCtx.partyIdTo"/>
         <set from-field="returnHeader.originContactMechId" field="shipmentCtx.originContactMechId"/>
         <set from-field="returnHeader.destinationFacilityId" field="shipmentCtx.destinationFacilityId"/>
-
+        <set from-field="returnHeader.returnId" field="shipmentCtx.primaryReturnId"/>
         <!-- later different behavior for customer vs. returns would happen here -->
-        <if-compare value="CUSTOMER_RETURN" field="returnHeader.returnHeaderTypeId" operator="equals">
-            <set value="SALES_RETURN" field="shipmentCtx.shipmentTypeId"/>
-            <set value="PURCH_SHIP_CREATED" field="shipmentCtx.statusId"/>  <!-- we may later need different status codes for return shipments -->
+        <if>
+            <condition>
+                <if-compare value="CUSTOMER_RETURN" field="returnHeader.returnHeaderTypeId" operator="equals"/>
+            </condition>
+            <then>
+                <set field="shipmentCtx.shipmentTypeId" value="SALES_RETURN"/>
+                <set field="shipmentCtx.statusId" value="PURCH_SHIP_CREATED"/>  <!-- we may later need different status codes for return shipments -->
+            </then>
+        <else-if>
+            <condition>
+                <if-compare value="VENDOR_RETURN" field="returnHeader.returnHeaderTypeId" operator="equals"/>
+            </condition>
+            <then>
+                <set field="shipmentCtx.shipmentTypeId" value="PURCHASE_RETURN" />
+                <set field="shipmentCtx.statusId" value="SHIPMENT_INPUT"/>
+            </then>        
+        </else-if>
         <else>
-            <add-error>
-                <fail-message message="${returnHeader.returnTypeId} is not supported"/>
+             <add-error>
+                <fail-message message="${returnHeader.returnHeaderTypeId} is not supported"/>
             </add-error>
             <check-errors/>
         </else>
-        </if-compare>        
+        </if>
+        
         <call-service service-name="createShipment" in-map-name="shipmentCtx">
             <result-to-field result-name="shipmentId"/>
         </call-service>
@@ -310,6 +325,38 @@
         
         <field-to-result field-name="shipmentId"/>
     </simple-method>
+    
+    <simple-method method-name="createShipmentAndItemsForVendorReturn" short-description="Create Shipment and ShipmentItems based on primaryReturnId for Vendor return">
+        <set-service-fields service-name="createShipment" map-name="parameters" to-map-name="shipmentCtx"/>
+        <call-service service-name="createShipment" in-map-name="shipmentCtx">
+            <result-to-field result-name="shipmentId"/>
+        </call-service>
+        <check-errors/>
+        <log level="info" message="Created new shipment ${shipmentId}"/>
+
+        <entity-condition entity-name="ReturnItem" list-name="returnItems">
+            <condition-expr field-name="returnId" operator="equals" env-name="parameters.primaryReturnId"/>
+        </entity-condition>
+        <iterate entry-name="returnItem" list-name="returnItems">
+            <clear-field field-name="shipItemCtx"/>
+            <set from-field="shipmentId" field="shipItemCtx.shipmentId"/>
+            <set from-field="returnItem.productId" field="shipItemCtx.productId"/>
+            <set from-field="returnItem.returnQuantity" field="shipItemCtx.quantity"/>
+            <log level="info" message="calling create shipment item with ${shipItemCtx}"/>
+            <call-service service-name="createShipmentItem" in-map-name="shipItemCtx">
+                <result-to-field result-name="shipmentItemSeqId"/>
+            </call-service>
+            <clear-field field-name="shipItemCtx"/>
+            <set from-field="shipmentId" field="shipItemCtx.shipmentId"/>
+            <set from-field="shipmentItemSeqId" field="shipItemCtx.shipmentItemSeqId"/>
+            <set from-field="returnItem.returnId" field="shipItemCtx.returnId"/>
+            <set from-field="returnItem.returnItemSeqId" field="shipItemCtx.returnItemSeqId"/>
+            <set from-field="returnItem.returnQuantity" field="shipItemCtx.quantity"/>
+            <call-service service-name="createReturnItemShipment" in-map-name="shipItemCtx"/>
+        </iterate>
+        
+        <field-to-result field-name="shipmentId"/>
+    </simple-method>    
 
     <simple-method method-name="setShipmentSettingsFromPrimaryOrder" short-description="Set Shipment Settings From Primary Order">
         <check-permission permission="FACILITY" action="_CREATE">

Modified: ofbiz/trunk/applications/product/servicedef/secas_shipment.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/servicedef/secas_shipment.xml?rev=680690&r1=680689&r2=680690&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/servicedef/secas_shipment.xml (original)
+++ ofbiz/trunk/applications/product/servicedef/secas_shipment.xml Tue Jul 29 06:28:52 2008
@@ -75,7 +75,15 @@
         <condition field-name="shipmentTypeId" operator="equals" value="SALES_RETURN"/>
         <action service="createInvoicesFromReturnShipment" mode="sync" run-as-user="system"/>
     </eca>
-
+    
+    <!-- if new status of a PURCHASE_RETURN is SHIPMENT_SHIPPED, create a return invoice -->
+    <eca service="updateShipment" event="commit">
+        <condition-field field-name="statusId" operator="not-equals" to-field-name="oldStatusId"/>
+        <condition field-name="statusId" operator="equals" value="SHIPMENT_SHIPPED"/>
+        <condition field-name="shipmentTypeId" operator="equals" value="PURCHASE_RETURN"/>
+        <action service="createInvoicesFromReturnShipment" mode="sync" run-as-user="system"/>
+    </eca>
+    
     <!-- if new statusId is SHIPMENT_SCHEDULED, send notification -->
     <eca service="createShipment" event="commit">
         <condition field-name="statusId" operator="equals" value="SHIPMENT_SCHEDULED"/>

Modified: ofbiz/trunk/applications/product/servicedef/services_facility.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/servicedef/services_facility.xml?rev=680690&r1=680689&r2=680690&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/servicedef/services_facility.xml (original)
+++ ofbiz/trunk/applications/product/servicedef/services_facility.xml Tue Jul 29 06:28:52 2008
@@ -234,6 +234,14 @@
         <attribute name="wholeSalePrice" mode="OUT" type="Double" optional="true"/>
         <attribute name="usageQuantity" mode="OUT" type="Double" optional="true"/>
     </service>
+    <service name="getInventoryItemForAssociatedOrderSupplierAndProduct" engine="simple"
+             location="org/ofbiz/product/inventory/InventoryServices.xml" invoke="getInventoryItemForAssociatedOrderSupplierAndProduct" auth="false">
+        <description>Get Inventory Items that are received against an order, supplier and product</description>
+        <attribute name="orderId" type="String" mode="IN" optional="true"/>
+        <attribute name="partyId" type="String" mode="IN" optional="true"/>
+        <attribute name="productId" type="String" mode="IN" optional="false"/>
+        <attribute name="inventoryItems" type="List" mode="OUT" optional="false"/>
+    </service>    
     <service name="checkInventoryAvailability" engine="java"
             location="org.ofbiz.product.inventory.InventoryServices" invoke="checkInventoryAvailability">
         <description>Batch service for checking and sending backorder notifications.  Will also set an autoCancelDate for sales orders to 30 days (hard coded)