Author: mor
Date: Mon Jul 20 12:59:57 2009 New Revision: 795809 URL: http://svn.apache.org/viewvc?rev=795809&view=rev Log: Payment capture is now triggered when invoice status is moved to Ready status. This event is removed from createInvoiceForOrder service. This work in following manner. (Modified notes from Jacopo on dev list) a) if ProductStore.autoApproveInvoice = Y then the invoice will be automatically moved to the ready status, this will trigger the capturePaymentsByInvoice service and everything will work as now. b) if ProductStore.autoApproveInvoice = N then the invoice will stay in the in-process status and payments will not be captured. Redesigned the ECA rules as updateShipment --> PICKED: trigger createInvoicesFromShipment (invoice in status IN PROCESS is created) ProductStore.autoApproveInvoice = Y: calls setInvoiceStatus to move the invoice status to READY. setInvoiceStatus trigger capturePaymentsByInvoice. updateShipment --> PACKED: trigger createInvoicesFromShipment and setInvoicesToReadyFromShipment. The former creates invoice(s) for missing ones and the latter moves the status of invoice to READY using setInvoiceStatus service. The setInvoiceStatus trigger capturePaymentsByInvoice. Patch applied from OFBIZ-2740 (https://issues.apache.org/jira/browse/OFBIZ-2740) Modified: ofbiz/trunk/applications/accounting/servicedef/secas.xml ofbiz/trunk/applications/accounting/servicedef/services_invoice.xml ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/invoice/InvoiceServices.java ofbiz/trunk/applications/product/servicedef/secas_shipment.xml Modified: ofbiz/trunk/applications/accounting/servicedef/secas.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/accounting/servicedef/secas.xml?rev=795809&r1=795808&r2=795809&view=diff ============================================================================== --- ofbiz/trunk/applications/accounting/servicedef/secas.xml (original) +++ ofbiz/trunk/applications/accounting/servicedef/secas.xml Mon Jul 20 12:59:57 2009 @@ -20,11 +20,7 @@ <service-eca xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/service-eca.xsd"> - <eca service="createInvoiceForOrder" event="return"> - <condition field-name="invoiceId" operator="is-not-empty"/> - <condition field-name="invoiceTypeId" operator="equals" value="SALES_INVOICE"/> - <action service="capturePaymentsByInvoice" mode="sync"/> - </eca> + <eca service="createPaymentApplication" event="commit"> <condition field-name="invoiceId" operator="is-not-empty"/> <action service="checkInvoicePaymentApplications" mode="sync"/> @@ -164,4 +160,12 @@ <action service="createAcctgTransAndEntriesForPaymentApplication" mode="sync"/> </eca> + <eca service="setInvoiceStatus" event="commit"> + <condition field-name="invoiceId" operator="is-not-empty"/> + <condition field-name="statusId" operator="equals" value="INVOICE_READY"/> + <condition field-name="oldStatusId" operator="not-equals" value="INVOICE_READY"/> + <condition field-name="oldStatusId" operator="not-equals" value="INVOICE_PAID"/> + <action service="checkInvoicePaymentApplications" mode="sync"/> + <action service="capturePaymentsByInvoice" mode="sync"/> + </eca> </service-eca> Modified: ofbiz/trunk/applications/accounting/servicedef/services_invoice.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/accounting/servicedef/services_invoice.xml?rev=795809&r1=795808&r2=795809&view=diff ============================================================================== --- ofbiz/trunk/applications/accounting/servicedef/services_invoice.xml (original) +++ ofbiz/trunk/applications/accounting/servicedef/services_invoice.xml Mon Jul 20 12:59:57 2009 @@ -206,6 +206,12 @@ <attribute name="shipmentId" type="String" mode="IN" optional="false"/> <attribute name="invoicesCreated" type="List" mode="OUT" optional="true"/> </service> + <service name="setInvoicesToReadyFromShipment" engine="java" + location="org.ofbiz.accounting.invoice.InvoiceServices" invoke="setInvoicesToReadyFromShipment"> + <description>Set invoice(s) to Ready from Shipment</description> + <attribute name="shipmentId" type="String" mode="IN" optional="false"/> + </service> + <service name="createSalesInvoicesFromDropShipment" engine="java" location="org.ofbiz.accounting.invoice.InvoiceServices" invoke="createSalesInvoicesFromDropShipment"> <description> 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=795809&r1=795808&r2=795809&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 Mon Jul 20 12:59:57 2009 @@ -46,6 +46,7 @@ import org.ofbiz.entity.GenericDelegator; import org.ofbiz.entity.GenericEntityException; import org.ofbiz.entity.GenericValue; +import org.ofbiz.entity.util.EntityFindOptions; import org.ofbiz.entity.util.EntityUtil; import org.ofbiz.entity.condition.EntityCondition; import org.ofbiz.entity.condition.EntityOperator; @@ -814,12 +815,6 @@ } } - // check to see if we are all paid up - Map checkResp = dispatcher.runSync("checkInvoicePaymentApplications", UtilMisc.<String, Object>toMap("invoiceId", invoiceId, "userLogin", userLogin)); - if (ServiceUtil.isError(checkResp)) { - return ServiceUtil.returnError(UtilProperties.getMessage(resource,"AccountingErrorCreatingInvoiceFromOrderCheckPaymentAppl",locale), null, null, checkResp); - } - Map resp = ServiceUtil.returnSuccess(); resp.put("invoiceId", invoiceId); resp.put("invoiceTypeId", invoiceType); @@ -1068,6 +1063,99 @@ return response; } + public static Map setInvoicesToReadyFromShipment(DispatchContext dctx, Map context) { + GenericDelegator delegator = dctx.getDelegator(); + LocalDispatcher dispatcher = dctx.getDispatcher(); + String shipmentId = (String) context.get("shipmentId"); + Locale locale = (Locale) context.get("locale"); + GenericValue userLogin = (GenericValue) context.get("userLogin"); + + // 1. Find all the orders for this shipment + // 2. For every order check the invoice + // 2.a If the invoice is in In-Process status, then move its status to ready and capture the payment. + // 2.b If the invoice is in status other then IN-Process, skip this. These would be already paid and captured. + + GenericValue shipment = null; + try { + shipment = delegator.findByPrimaryKey("Shipment", UtilMisc.toMap("shipmentId", shipmentId)); + } catch (GenericEntityException e) { + String errMsg = UtilProperties.getMessage(resource, "AccountingTroubleGettingShipmentEntity", UtilMisc.toMap("shipmentId",shipmentId), locale); + Debug.logError(e, errMsg, module); + return ServiceUtil.returnError(errMsg); + } + List<GenericValue> itemIssuances = FastList.newInstance(); + try { + EntityFindOptions findOptions = new EntityFindOptions(); + findOptions.setDistinct(true); + Set<String> fieldsToSelect = UtilMisc.toSet("orderId", "shipmentId"); + itemIssuances = delegator.findList("ItemIssuance", EntityCondition.makeCondition("shipmentId", shipmentId), fieldsToSelect, UtilMisc.toList("orderId"), findOptions, false); + } catch (GenericEntityException e) { + String errMsg = UtilProperties.getMessage(resource, "AccountingProblemGettingItemsFromShipments", locale); + Debug.logError(e, errMsg, module); + return ServiceUtil.returnError(errMsg); + } + if (itemIssuances.size() == 0) { + Debug.logInfo("No items issued for shipments", module); + return ServiceUtil.returnSuccess(); + } + // The orders can now be placed in separate groups, each for + // 1. The group of orders for which payment is already captured. No grouping and action required. + // 2. The group of orders for which invoice is IN-Process status. + Map ordersWithInProcessInvoice = FastMap.newInstance(); + + for (GenericValue itemIssuance : itemIssuances) { + String orderId = itemIssuance.getString("orderId"); + Map billFields = FastMap.newInstance(); + billFields.put("orderId", orderId); + + List orderItemBillings = FastList.newInstance(); + try { + orderItemBillings = delegator.findByAnd("OrderItemBilling", billFields); + } catch (GenericEntityException e) { + String errMsg = UtilProperties.getMessage(resource, "AccountingProblemLookingUpOrderItemBilling", UtilMisc.toMap("billFields", billFields), locale); + Debug.logError(e, errMsg, module); + return ServiceUtil.returnError(errMsg); + } + // if none found, the order does not have any invoice + if (orderItemBillings.size() != 0) { + // orders already have an invoice + GenericValue orderItemBilling = EntityUtil.getFirst(orderItemBillings); + GenericValue invoice = null; + try { + invoice = orderItemBilling.getRelatedOne("Invoice"); + } catch (GenericEntityException e) { + Debug.logError(e, module); + return ServiceUtil.returnError(e.getMessage()); + } + if (invoice != null) { + if ("INVOICE_IN_PROCESS".equals(invoice.getString("statusId"))) { + ordersWithInProcessInvoice.put(orderId, invoice); + } + } + } + } + + // For In-Process invoice, move the status to ready and capture the payment + Set invoicesInProcess = ordersWithInProcessInvoice.keySet(); + Iterator iter = invoicesInProcess.iterator(); + while (iter.hasNext()) { + String orderId = (String) iter.next(); + GenericValue invoice = (GenericValue) ordersWithInProcessInvoice.get(orderId); + String invoiceId = invoice.getString("invoiceId"); + Map setInvoiceStatusResult = FastMap.newInstance(); + try { + setInvoiceStatusResult = dispatcher.runSync("setInvoiceStatus", UtilMisc.<String, Object>toMap("invoiceId", invoiceId, "statusId", "INVOICE_READY", "userLogin", userLogin)); + } catch (GenericServiceException e) { + Debug.logError(e, module); + return ServiceUtil.returnError(e.getMessage()); + } + if (ServiceUtil.isError(setInvoiceStatusResult)) { + return ServiceUtil.returnError(UtilProperties.getMessage(resource,"AccountingErrorCreatingInvoiceFromOrder",locale), null, null, setInvoiceStatusResult); + } + } + return ServiceUtil.returnSuccess(); + } + public static Map createSalesInvoicesFromDropShipment(DispatchContext dctx, Map context) { LocalDispatcher dispatcher = dctx.getDispatcher(); String shipmentId = (String) context.get("shipmentId"); Modified: ofbiz/trunk/applications/product/servicedef/secas_shipment.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/servicedef/secas_shipment.xml?rev=795809&r1=795808&r2=795809&view=diff ============================================================================== --- ofbiz/trunk/applications/product/servicedef/secas_shipment.xml (original) +++ ofbiz/trunk/applications/product/servicedef/secas_shipment.xml Mon Jul 20 12:59:57 2009 @@ -27,13 +27,22 @@ <condition field-name="statusId" operator="equals" value="SHIPMENT_CANCELLED"/> <action service="checkCancelItemIssuanceAndOrderShipmentFromShipment" mode="sync"/> </eca> - <!-- if new statusId of a SALES_SHIPMENT is SHIPMENT_PACKED, create invoice --> + <!-- if new statusId of a SALES_SHIPMENT is SHIPMENT_PICKED, create 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_PICKED"/> + <condition field-name="shipmentTypeId" operator="equals" value="SALES_SHIPMENT"/> + <action service="createInvoicesFromShipment" mode="sync" run-as-user="system"/> + </eca> + <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_PACKED"/> <condition field-name="shipmentTypeId" operator="equals" value="SALES_SHIPMENT"/> <action service="createInvoicesFromShipment" mode="sync" run-as-user="system"/> + <action service="setInvoicesToReadyFromShipment" mode="sync" run-as-user="system"/> </eca> + <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"/> @@ -120,6 +129,7 @@ <condition field-name="primaryOrderId" operator="is-not-empty"/> <action service="setShipmentSettingsFromPrimaryOrder" mode="sync"/> </eca> + <eca service="updateShipment" event="commit"> <condition-field field-name="primaryOrderId" operator="not-equals" to-field-name="oldPrimaryOrderId"/> <condition field-name="primaryOrderId" operator="is-not-empty"/> |
Free forum by Nabble | Edit this page |