You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by si...@apache.org on 2006/11/02 02:31:41 UTC
svn commit: r470173 - in /incubator/ofbiz/trunk/applications/accounting:
config/AccountingUiLabels.properties servicedef/services_invoice.xml
src/org/ofbiz/accounting/invoice/InvoiceServices.java
Author: sichen
Date: Wed Nov 1 17:31:40 2006
New Revision: 470173
URL: http://svn.apache.org/viewvc?view=rev&rev=470173
Log:
Invoicing services now support pro-rating of taxes based on product store settings and invoicing of additional shipping charges from the Shipment entity
Modified:
incubator/ofbiz/trunk/applications/accounting/config/AccountingUiLabels.properties
incubator/ofbiz/trunk/applications/accounting/servicedef/services_invoice.xml
incubator/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/invoice/InvoiceServices.java
Modified: incubator/ofbiz/trunk/applications/accounting/config/AccountingUiLabels.properties
URL: http://svn.apache.org/viewvc/incubator/ofbiz/trunk/applications/accounting/config/AccountingUiLabels.properties?view=diff&rev=470173&r1=470172&r2=470173
==============================================================================
--- incubator/ofbiz/trunk/applications/accounting/config/AccountingUiLabels.properties (original)
+++ incubator/ofbiz/trunk/applications/accounting/config/AccountingUiLabels.properties Wed Nov 1 17:31:40 2006
@@ -538,7 +538,6 @@
AccountingErrorCreatingInvoiceFromOrderCheckPaymentAppl=Error creating invoice from order while checking payment applications
AccountingEntityDataProblemCreatingInvoiceFromOrderItems=Entity/data problem creating invoice from order items: ${reason}
AccountingServiceOtherProblemCreatingInvoiceFromOrderItems=Service/other problem creating invoice from order items: ${reason}
-AccountingTroubleCreateInvoicesFromShipmentsService=Trouble calling createInvoicesFromShipments service; invoice not created for shipment [${shipmentId}]
AccountingShipmentsOfDifferentTypes=Shipments of different types found; shipment [${tmpShipmentId}] of type [${shipmentTypeId}] is of different type from the previous ones.
AccountingTroubleGettingShipmentEntity=Trouble getting Shipment entity for shipment [${tmpShipmentId}]
AccountingProblemGettingItemsFromShipments=Problem getting issued items from shipments
@@ -599,6 +598,18 @@
AccountingInvoiceCommissionNoItems=No order or return items, not creating commission invoice
AccountingInvoiceCommissionEntityDataProblem=Entity/data problem creating commission invoice: ${reason}
AccountingPageTitleAgreementPriceList=Agreement Price List
+AccountingAdditionalShippingChargeForShipment=Additional Shipping Charge For Shipment
+AccountingUnableToAuthAdditionalShipCharges=Unable to authorize additional shipping charges for shipmentId ${shipmentId} to paymentMethodId ${paymentMethodId} (orderPaymentPreferenceId ${orderPaymentPreferenceId})
+AccountingTroubleCallingAuthOrderPaymentPreferenceService=Trouble calling authOrderPaymentPreference service
+AccountingTroubleCallingCreateInvoicesFromShipmentService=Trouble calling createInvoicesFromShipment service; invoice not created for shipment [${shipmentId}]
+AccountingTroubleCallingCreateInvoicesFromShipmentsService=Trouble calling createInvoicesFromShipments service
+AccountingTroubleCallingCreateOrderAdjustmentService=Trouble calling createOrderAdjustment service
+AccountingProblemGettingOrderPaymentPreferences=Problem getting OrderPaymentPreference records
+AccountingTroubleCallingCreateOrderPaymentPreferenceService=Trouble calling createOrderPaymentPreference service
+AccountingTroubleCallingCalcTaxService=Trouble calling calcTaxService
+AccountingProblemStoringOrderAdjustments=Problem storing OrderAdjustments: ${orderAdjustments}
+AccountingErrorCreatingOrderAdjustmentBillingFromOrder=Error creating OrderAdjustmentBilling from order
+AccountingTroubleCallingCalculateInvoicedAdjustmentTotalService=Accounting trouble calling calculateInvoicedAdjustmentTotal service
#Potentional Common definitions
FormFieldTitle_emailAddressFrom=From Emailadress
Modified: incubator/ofbiz/trunk/applications/accounting/servicedef/services_invoice.xml
URL: http://svn.apache.org/viewvc/incubator/ofbiz/trunk/applications/accounting/servicedef/services_invoice.xml?view=diff&rev=470173&r1=470172&r2=470173
==============================================================================
--- incubator/ofbiz/trunk/applications/accounting/servicedef/services_invoice.xml (original)
+++ incubator/ofbiz/trunk/applications/accounting/servicedef/services_invoice.xml Wed Nov 1 17:31:40 2006
@@ -254,4 +254,10 @@
<auto-attributes entity-name="InvoiceContactMech" include="pk" mode="IN" optional="false"/>
<attribute name="contactMechId" type="String" mode="OUT" optional="true"/>
</service>
+ <service name="calculateInvoicedAdjustmentTotal" engine="java"
+ location="org.ofbiz.accounting.invoice.InvoiceServices" invoke="calculateInvoicedAdjustmentTotalBd">
+ <description>Calculate the previously invoiced amount for an OrderAdjustment</description>
+ <attribute name="orderAdjustment" type="GenericValue" mode="IN" optional="false"/>
+ <attribute name="invoicedTotal" type="BigDecimal" mode="OUT" optional="false"/>
+ </service>
</services>
Modified: incubator/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/invoice/InvoiceServices.java
URL: http://svn.apache.org/viewvc/incubator/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/invoice/InvoiceServices.java?view=diff&rev=470173&r1=470172&r2=470173
==============================================================================
--- incubator/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/invoice/InvoiceServices.java (original)
+++ incubator/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/invoice/InvoiceServices.java Wed Nov 1 17:31:40 2006
@@ -41,6 +41,7 @@
import org.ofbiz.entity.GenericDelegator;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.util.EntityUtil;
import org.ofbiz.entity.condition.EntityCondition;
import org.ofbiz.entity.condition.EntityOperator;
import org.ofbiz.entity.condition.EntityExpr;
@@ -473,6 +474,23 @@
while (itemAdjIter.hasNext()) {
GenericValue adj = (GenericValue) itemAdjIter.next();
+ // Check against OrderAdjustmentBilling to see how much of this adjustment has already been invoiced
+ BigDecimal adjAlreadyInvoicedAmount = null;
+ try {
+ Map checkResult = dispatcher.runSync("calculateInvoicedAdjustmentTotal", UtilMisc.toMap("orderAdjustment", adj));
+ adjAlreadyInvoicedAmount = (BigDecimal) checkResult.get("invoicedTotal");
+ } catch (GenericServiceException e) {
+ String errMsg = UtilProperties.getMessage(resource, "AccountingTroubleCallingCalculateInvoicedAdjustmentTotalService", locale);
+ Debug.logError(e, errMsg, module);
+ return ServiceUtil.returnError(errMsg);
+ }
+
+ // If the absolute invoiced amount >= the abs of the adjustment amount, the full amount has already been invoiced,
+ // so skip this adjustment
+ if (adjAlreadyInvoicedAmount.abs().compareTo(adj.getBigDecimal("amount").setScale(decimals, rounding).abs()) > 0) {
+ continue;
+ }
+
BigDecimal amount = new BigDecimal(0);
if (adj.get("amount") != null) {
// pro-rate the amount
@@ -520,7 +538,20 @@
if (ServiceUtil.isError(createInvoiceItemAdjResult)) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource,"AccountingErrorCreatingInvoiceItemFromOrder",locale), null, null, createInvoiceItemAdjResult);
}
-
+
+ // Create the OrderAdjustmentBilling record
+ Map createOrderAdjustmentBillingContext = FastMap.newInstance();
+ createOrderAdjustmentBillingContext.put("orderAdjustmentId", adj.getString("orderAdjustmentId"));
+ createOrderAdjustmentBillingContext.put("invoiceId", invoiceId);
+ createOrderAdjustmentBillingContext.put("invoiceItemSeqId", invoiceItemSeqId);
+ createOrderAdjustmentBillingContext.put("amount", new Double(amount.doubleValue()));
+ createOrderAdjustmentBillingContext.put("userLogin", userLogin);
+
+ Map createOrderAdjustmentBillingResult = dispatcher.runSync("createOrderAdjustmentBilling", createOrderAdjustmentBillingContext);
+ if (ServiceUtil.isError(createOrderAdjustmentBillingResult)) {
+ return ServiceUtil.returnError(UtilProperties.getMessage(resource,"AccountingErrorCreatingOrderAdjustmentBillingFromOrder",locale), null, null, createOrderAdjustmentBillingContext);
+ }
+
// this adjustment amount
BigDecimal thisAdjAmount = new BigDecimal(amount.doubleValue()).setScale(decimals, rounding);
@@ -545,22 +576,40 @@
}
// create header adjustments as line items -- always to tax/shipping last
- List shipAdjustments = new ArrayList();
- List taxAdjustments = new ArrayList();
+ Map shipAdjustments = new HashMap();
+ Map taxAdjustments = new HashMap();
List headerAdjustments = orh.getOrderHeaderAdjustments();
Iterator headerAdjIter = headerAdjustments.iterator();
while (headerAdjIter.hasNext()) {
GenericValue adj = (GenericValue) headerAdjIter.next();
+
+ // Check against OrderAdjustmentBilling to see how much of this adjustment has already been invoiced
+ BigDecimal adjAlreadyInvoicedAmount = null;
+ try {
+ Map checkResult = dispatcher.runSync("calculateInvoicedAdjustmentTotal", UtilMisc.toMap("orderAdjustment", adj));
+ adjAlreadyInvoicedAmount = ((BigDecimal) checkResult.get("invoicedTotal")).setScale(decimals, rounding);
+ } catch (GenericServiceException e) {
+ String errMsg = UtilProperties.getMessage(resource, "AccountingTroubleCallingCalculateInvoicedAdjustmentTotalService", locale);
+ Debug.logError(e, errMsg, module);
+ return ServiceUtil.returnError(errMsg);
+ }
+
+ // If the absolute invoiced amount >= the abs of the adjustment amount, the full amount has already been invoiced,
+ // so skip this adjustment
+ if (adjAlreadyInvoicedAmount.abs().compareTo(adj.getBigDecimal("amount").setScale(decimals, rounding).abs()) > 0) {
+ continue;
+ }
+
if ("SHIPPING_CHARGES".equals(adj.getString("orderAdjustmentTypeId"))) {
- shipAdjustments.add(adj);
+ shipAdjustments.put(adj, adjAlreadyInvoicedAmount);
} else if ("SALES_TAX".equals(adj.getString("orderAdjustmentTypeId"))) {
- taxAdjustments.add(adj);
+ taxAdjustments.put(adj, adjAlreadyInvoicedAmount);
} else {
// these will effect the shipping pro-rate (unless commented)
// other adjustment type
BigDecimal adjAmount = calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId,
- orderSubTotal, invoiceSubTotal, invoiceQuantity, decimals, rounding, userLogin, dispatcher, locale);
+ orderSubTotal, invoiceSubTotal, adj.getBigDecimal("amount").setScale(decimals, rounding), decimals, rounding, userLogin, dispatcher, locale);
// invoiceShipProRateAmount += adjAmount;
// do adjustments compound or are they based off subtotal? Here we will (unless commented)
// invoiceSubTotal += adjAmount;
@@ -573,41 +622,79 @@
// next do the shipping adjustments. Note that we do not want to add these to the invoiceSubTotal or orderSubTotal for pro-rating tax later, as that would cause
// numerator/denominator problems when the shipping is not pro-rated but rather charged all on the first invoice
- Iterator shipAdjIter = shipAdjustments.iterator();
+ Iterator shipAdjIter = shipAdjustments.keySet().iterator();
while (shipAdjIter.hasNext()) {
GenericValue adj = (GenericValue) shipAdjIter.next();
+ BigDecimal adjAlreadyInvoicedAmount = (BigDecimal) shipAdjustments.get(adj);
+
if ("N".equalsIgnoreCase(prorateShipping)) {
- if (previousInvoiceFound) {
- Debug.logInfo("Previous invoice found for this order [" + orderId + "]; shipping already billed", module);
- continue;
- } else {
- // this is the first invoice; bill it all now
- BigDecimal adjAmount = calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId,
- new BigDecimal("1"), new BigDecimal("1"), totalItemsInOrder, decimals, rounding, userLogin, dispatcher, locale);
- // increment the counter
- invoiceItemSeqNum++;
- invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, 2);
- }
+
+ // Set the divisor and multiplier to 1 to avoid prorating
+ BigDecimal divisor = new BigDecimal("1");
+ BigDecimal multiplier = new BigDecimal("1");
+
+ // The base amount in this case is the adjustment amount minus the total already invoiced for that adjustment, since
+ // it won't be prorated
+ BigDecimal baseAmount = adj.getBigDecimal("amount").setScale(decimals, rounding).subtract(adjAlreadyInvoicedAmount);
+ BigDecimal adjAmount = calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId,
+ divisor, multiplier, baseAmount, decimals, rounding, userLogin, dispatcher, locale);
} else {
- // pro-rate the shipping amount based on shippable information
+
+ // Pro-rate the shipping amount based on shippable information
+ BigDecimal divisor = shippableAmount;
+ BigDecimal multiplier = invoiceShipProRateAmount;
+
+ // The base amount in this case is the adjustment amount, since we want to prorate based on the full amount
+ BigDecimal baseAmount = adj.getBigDecimal("amount").setScale(decimals, rounding);
BigDecimal adjAmount = calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId,
- shippableAmount, invoiceShipProRateAmount, invoiceQuantity, decimals, rounding, userLogin, dispatcher, locale);
- // increment the counter
- invoiceItemSeqNum++;
- invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, 2);
+ divisor, multiplier, baseAmount, decimals, rounding, userLogin, dispatcher, locale);
}
+
+ // Increment the counter
+ invoiceItemSeqNum++;
+ invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, 2);
}
// last do the tax adjustments
- Iterator taxAdjIter = taxAdjustments.iterator();
+ String prorateTaxes = productStore.getString("prorateTaxes");
+ if (prorateTaxes == null) {
+ prorateTaxes = "Y";
+ }
+ Iterator taxAdjIter = taxAdjustments.keySet().iterator();
while (taxAdjIter.hasNext()) {
GenericValue adj = (GenericValue) taxAdjIter.next();
- // note this should use invoice decimals & rounding instead of taxDecimals and taxRounding, because it will be added to the invoice
- BigDecimal adjAmount = calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId,
- orderSubTotal, invoiceSubTotal, invoiceQuantity, decimals, rounding, userLogin, dispatcher, locale);
- // this doesn't really effect anything; but just for our totals
- // since it will no longer be used in pro-rating, we can just round off now
+ BigDecimal adjAlreadyInvoicedAmount = (BigDecimal) taxAdjustments.get(adj);
+ BigDecimal adjAmount = null;
+
+ if ("N".equalsIgnoreCase(prorateTaxes)) {
+
+ // Set the divisor and multiplier to 1 to avoid prorating
+ BigDecimal divisor = new BigDecimal("1");
+ BigDecimal multiplier = new BigDecimal("1");
+
+ // The base amount in this case is the adjustment amount minus the total already invoiced for that adjustment, since
+ // it won't be prorated
+ // Note this should use invoice decimals & rounding instead of taxDecimals and taxRounding for tax adjustments, because it will be added to the invoice
+ BigDecimal baseAmount = adj.getBigDecimal("amount").setScale(decimals, rounding).subtract(adjAlreadyInvoicedAmount);
+ adjAmount = calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId,
+ divisor, multiplier, baseAmount, decimals, rounding, userLogin, dispatcher, locale);
+ } else {
+
+ // Pro-rate the tax amount based on shippable information
+ BigDecimal divisor = orderSubTotal;
+ BigDecimal multiplier = invoiceSubTotal;
+
+ // The base amount in this case is the adjustment amount, since we want to prorate based on the full amount
+ // Note this should use invoice decimals & rounding instead of taxDecimals and taxRounding for tax adjustments, because it will be added to the invoice
+ BigDecimal baseAmount = adj.getBigDecimal("amount").setScale(decimals, rounding);
+ adjAmount = calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId,
+ divisor, multiplier, baseAmount, decimals, rounding, userLogin, dispatcher, locale);
+ }
invoiceSubTotal = invoiceSubTotal.add(adjAmount).setScale(decimals, rounding);
+
+ // Increment the counter
+ invoiceItemSeqNum++;
+ invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, 2);
}
// check for previous order payments
@@ -889,8 +976,8 @@
Map result = dispatcher.runSync("createInvoicesFromShipments", serviceContext);
invoicesCreated = (List) result.get("invoicesCreated");
} catch (GenericServiceException e) {
- Debug.logError(e, "Trouble calling createInvoicesFromShipments service; invoice not created for shipment [" + shipmentId + "]", module);
- return ServiceUtil.returnError(UtilProperties.getMessage(resource,"AccountingTroubleCreateInvoicesFromShipmentsService",UtilMisc.toMap("shipmentId",shipmentId),locale));
+ Debug.logError(e, "Trouble calling createInvoicesFromShipment service; invoice not created for shipment [" + shipmentId + "]", module);
+ return ServiceUtil.returnError(UtilProperties.getMessage(resource,"AccountingTroubleCallingCreateInvoicesFromShipmentService",UtilMisc.toMap("shipmentId",shipmentId),locale));
}
Map response = ServiceUtil.returnSuccess();
response.put("invoicesCreated", invoicesCreated);
@@ -1066,6 +1153,180 @@
itemQtyAvail.put(issue.getString("orderItemSeqId"), billAvail);
}
+ OrderReadHelper orh = new OrderReadHelper(delegator, orderId);
+ GenericValue productStore = orh.getProductStore();
+
+ // If shipping charges are not prorated, the shipments need to be examined for additional shipping charges
+ if (productStore.getString("prorateShipping").equals("N")) {
+
+ // Get the set of filtered shipments
+ List invoiceableShipmentIds = EntityUtil.getFieldListFromEntityList(toBillItems, "shipmentId", true);
+ List invoiceableShipments = null;
+ try {
+ invoiceableShipments = delegator.findByCondition("Shipment", new EntityExpr("shipmentId", EntityOperator.IN, invoiceableShipmentIds), null, null);
+ } catch( GenericEntityException e ) {
+ String errMsg = UtilProperties.getMessage(resource, "AccountingTroubleCallingCreateInvoicesFromShipmentsService", locale);
+ Debug.logError(e, errMsg, module);
+ return ServiceUtil.returnError(errMsg);
+ }
+
+ // Total the additional shipping charges for the shipments
+ Map additionalShippingCharges = new HashMap();
+ BigDecimal totalAdditionalShippingCharges = ZERO;
+ Iterator isit = invoiceableShipments.iterator();
+ while(isit.hasNext()) {
+ GenericValue shipment = (GenericValue) isit.next();
+ if (shipment.get("additionalShippingCharge") == null) continue;
+ BigDecimal shipmentAdditionalShippingCharges = shipment.getBigDecimal("additionalShippingCharge").setScale(decimals, rounding);
+ additionalShippingCharges.put(shipment, shipmentAdditionalShippingCharges);
+ totalAdditionalShippingCharges = totalAdditionalShippingCharges.add(shipmentAdditionalShippingCharges);
+ }
+
+ // If the additional shipping charges are greater than zero, process them
+ if (totalAdditionalShippingCharges.signum() == 1) {
+
+ // Add an OrderAdjustment to the order for each additional shipping charge
+ Iterator ascit = additionalShippingCharges.keySet().iterator();
+ while (ascit.hasNext()) {
+ GenericValue shipment = (GenericValue) ascit.next();
+ String shipmentId = shipment.getString("shipmentId");
+ BigDecimal additionalShippingCharge = (BigDecimal) additionalShippingCharges.get(shipment);
+ Map createOrderAdjustmentContext = new HashMap();
+ createOrderAdjustmentContext.put("orderId", orderId);
+ createOrderAdjustmentContext.put("orderAdjustmentTypeId", "SHIPPING_CHARGES");
+ createOrderAdjustmentContext.put("description", UtilProperties.getMessage(resource, "AccountingAdditionalShippingChargeForShipment", locale) + " #" + shipmentId);
+ createOrderAdjustmentContext.put("sourceReferenceId", shipmentId);
+ createOrderAdjustmentContext.put("amount", new Double(additionalShippingCharge.doubleValue()));
+ createOrderAdjustmentContext.put("userLogin", context.get("userLogin"));
+ String shippingOrderAdjustmentId = null;
+ try {
+ Map createOrderAdjustmentResult = dispatcher.runSync("createOrderAdjustment", createOrderAdjustmentContext);
+ shippingOrderAdjustmentId = (String) createOrderAdjustmentResult.get("orderAdjustmentId");
+ } catch (GenericServiceException e) {
+ String errMsg = UtilProperties.getMessage(resource, "AccountingTroubleCallingCreateOrderAdjustmentService", locale);
+ Debug.logError(e, errMsg, module);
+ return ServiceUtil.returnError(errMsg);
+ }
+
+ // Obtain a list of OrderAdjustments due to tax on the shipping charges, if any
+ GenericValue billToParty = orh.getBillToParty();
+ GenericValue payToParty = orh.getBillFromParty();
+ GenericValue destinationContactMech = null;
+ try {
+ destinationContactMech = shipment.getRelatedOne("DestinationPostalAddress");
+ } catch( GenericEntityException e ) {
+ String errMsg = UtilProperties.getMessage(resource, "AccountingTroubleCallingCreateInvoicesFromShipmentService", locale);
+ Debug.logError(e, errMsg, module);
+ return ServiceUtil.returnError(errMsg);
+ }
+
+ List emptyList = new ArrayList();
+ Map calcTaxContext = new HashMap();
+ calcTaxContext.put("productStoreId", orh.getProductStoreId());
+ calcTaxContext.put("payToPartyId", payToParty.getString("partyId"));
+ calcTaxContext.put("billToPartyId", billToParty.getString("partyId"));
+ calcTaxContext.put("orderShippingAmount", totalAdditionalShippingCharges);
+ calcTaxContext.put("shippingAddress", destinationContactMech);
+
+ // These parameters don't matter if we're only worried about adjustments on the shipping charges
+ calcTaxContext.put("itemProductList", emptyList);
+ calcTaxContext.put("itemAmountList", emptyList);
+ calcTaxContext.put("itemPriceList", emptyList);
+ calcTaxContext.put("itemShippingList", emptyList);
+
+ List orderAdjustments = null;
+ Map calcTaxResult = null;
+ try {
+ calcTaxResult = dispatcher.runSync("calcTax", calcTaxContext);
+ } catch (GenericServiceException e) {
+ String errMsg = UtilProperties.getMessage(resource, "AccountingTroubleCallingCalcTaxService", locale);
+ Debug.logError(e, errMsg, module);
+ return ServiceUtil.returnError(errMsg);
+ }
+ orderAdjustments = (List) calcTaxResult.get("orderAdjustments");
+
+ // If we have any OrderAdjustments due to tax on shipping, store them and add them to the total
+ if (calcTaxResult != null && orderAdjustments != null) {
+ Iterator oait = orderAdjustments.iterator();
+ while (oait.hasNext()) {
+ GenericValue orderAdjustment = (GenericValue) oait.next();
+ totalAdditionalShippingCharges = totalAdditionalShippingCharges.add(orderAdjustment.getBigDecimal("amount").setScale(decimals, rounding));
+ orderAdjustment.set("orderAdjustmentId", delegator.getNextSeqId("OrderAdjustment"));
+ orderAdjustment.set("orderId", orderId);
+ orderAdjustment.set("orderItemSeqId", "_NA_");
+ orderAdjustment.set("shipGroupSeqId", shipment.getString("primaryShipGroupSeqId"));
+ orderAdjustment.set("originalAdjustmentId", shippingOrderAdjustmentId);
+ }
+ try {
+ delegator.storeAll(orderAdjustments);
+ } catch( GenericEntityException e ) {
+ String errMsg = UtilProperties.getMessage(resource, "AccountingProblemStoringOrderAdjustments", UtilMisc.toMap("orderAdjustments", orderAdjustments), locale);
+ Debug.logError(e, errMsg, module);
+ return ServiceUtil.returnError(errMsg);
+ }
+ }
+
+ // If part of the order was paid via credit card, try to charge it for the additional shipping
+ List orderPaymentPreferences = new ArrayList();
+ try {
+ orderPaymentPreferences = delegator.findByAnd("OrderPaymentPreference", UtilMisc.toMap("orderId", orderId));
+ } catch( GenericEntityException e ) {
+ String errMsg = UtilProperties.getMessage(resource, "AccountingProblemGettingOrderPaymentPreferences", locale);
+ Debug.logError(e, errMsg, module);
+ return ServiceUtil.returnError(errMsg);
+ }
+
+ // Use the first credit card we find, for the sake of simplicity
+ String paymentMethodId = null;
+ Iterator oppit = orderPaymentPreferences.iterator();
+ while (oppit.hasNext()) {
+ GenericValue orderPaymentPreference = (GenericValue) oppit.next();
+ if (orderPaymentPreference.getString("paymentMethodTypeId").equals("CREDIT_CARD")) {
+ paymentMethodId = orderPaymentPreference.getString("paymentMethodId");
+ break;
+ }
+ }
+
+ if (paymentMethodId != null ) {
+
+ // Create a new OrderPaymentPreference for the order to handle the additional charge. Don't
+ // set the maxAmount so that it doesn't interfere with other authorizations
+ Map serviceContext = UtilMisc.toMap("orderId", orderId, "paymentMethodId", paymentMethodId, "paymentMethodTypeId", "CREDIT_CARD", "userLogin", context.get("userLogin"));
+ String orderPaymentPreferenceId = null;
+ try {
+ Map result = dispatcher.runSync("createOrderPaymentPreference", serviceContext);
+ orderPaymentPreferenceId = (String) result.get("orderPaymentPreferenceId");
+ } catch (GenericServiceException e) {
+ String errMsg = UtilProperties.getMessage(resource, "AccountingTroubleCallingCreateOrderPaymentPreferenceService", locale);
+ Debug.logError(e, errMsg, module);
+ return ServiceUtil.returnError(errMsg);
+ }
+
+ // Attempt to authorize the new orderPaymentPreference
+ Map authResult = null;
+ try {
+
+ // Use an overrideAmount because the maxAmount wasn't set on the OrderPaymentPreference
+ authResult = dispatcher.runSync("authOrderPaymentPreference", UtilMisc.toMap("orderPaymentPreferenceId", orderPaymentPreferenceId, "overrideAmount", new Double(totalAdditionalShippingCharges.doubleValue()), "userLogin", context.get("userLogin")));
+ } catch (GenericServiceException e) {
+ String errMsg = UtilProperties.getMessage(resource, "AccountingTroubleCallingAuthOrderPaymentPreferenceService", locale);
+ Debug.logError(e, errMsg, module);
+ return ServiceUtil.returnError(errMsg);
+ }
+
+ // If the authorization fails, create the invoice anyway, but make a note of it
+ boolean authFinished = ( (Boolean) authResult.get("finished") ).booleanValue();
+ boolean authErrors = ( (Boolean) authResult.get("errors") ).booleanValue();
+ if (authErrors || ! authFinished) {
+ String errMsg = UtilProperties.getMessage(resource, "AccountingUnableToAuthAdditionalShipCharges", UtilMisc.toMap("shipmentId", shipmentId, "paymentMethodId", paymentMethodId, "orderPaymentPreferenceId", orderPaymentPreferenceId), locale);
+ Debug.logError(errMsg, module);
+ }
+
+ }
+ }
+ }
+ }
+
// call the createInvoiceForOrder service for each order
Map serviceContext = UtilMisc.toMap("orderId", orderId, "billItems", toBillItems, "userLogin", context.get("userLogin"));
try {
@@ -1490,16 +1751,16 @@
}
private static BigDecimal calcHeaderAdj(GenericDelegator delegator, GenericValue adj, String invoiceTypeId, String invoiceId, String invoiceItemSeqId,
- BigDecimal divisor, BigDecimal multiplier, BigDecimal invoiceQuantity, int decimals, int rounding, GenericValue userLogin, LocalDispatcher dispatcher, Locale locale) {
+ BigDecimal divisor, BigDecimal multiplier, BigDecimal baseAmount, int decimals, int rounding, GenericValue userLogin, LocalDispatcher dispatcher, Locale locale) {
BigDecimal adjAmount = ZERO;
if (adj.get("amount") != null) {
+
// pro-rate the amount
- BigDecimal baseAdjAmount = adj.getBigDecimal("amount");
BigDecimal amount = ZERO;
// make sure the divisor is not 0 to avoid NaN problems; just leave the amount as 0 and skip it in essense
if (divisor.signum() != 0) {
// multiply first then divide to avoid rounding errors
- amount = baseAdjAmount.multiply(multiplier).divide(divisor, decimals, rounding);
+ amount = baseAmount.multiply(multiplier).divide(divisor, decimals, rounding);
}
if (amount.signum() != 0) {
Map createInvoiceItemContext = FastMap.newInstance();
@@ -1530,6 +1791,21 @@
if (ServiceUtil.isError(createInvoiceItemResult)) {
ServiceUtil.returnError(UtilProperties.getMessage(resource,"AccountingErrorCreatingInvoiceItemFromOrder",locale), null, null, createInvoiceItemResult);
}
+
+ // Create the OrderAdjustmentBilling record
+ Map createOrderAdjustmentBillingContext = FastMap.newInstance();
+ createOrderAdjustmentBillingContext.put("orderAdjustmentId", adj.getString("orderAdjustmentId"));
+ createOrderAdjustmentBillingContext.put("invoiceId", invoiceId);
+ createOrderAdjustmentBillingContext.put("invoiceItemSeqId", invoiceItemSeqId);
+ createOrderAdjustmentBillingContext.put("amount", new Double(amount.doubleValue()));
+ createOrderAdjustmentBillingContext.put("userLogin", userLogin);
+
+ try {
+ Map createOrderAdjustmentBillingResult = dispatcher.runSync("createOrderAdjustmentBilling", createOrderAdjustmentBillingContext);
+ } catch( GenericServiceException e ) {
+ ServiceUtil.returnError(UtilProperties.getMessage(resource,"AccountingErrorCreatingOrderAdjustmentBillingFromOrder",locale), null, null, createOrderAdjustmentBillingContext);
+ }
+
}
amount.setScale(decimals, rounding);
adjAmount = amount;
@@ -1573,6 +1849,21 @@
if (ServiceUtil.isError(createInvoiceItemResult)) {
ServiceUtil.returnError(UtilProperties.getMessage(resource,"AccountingErrorCreatingInvoiceItemFromOrder",locale), null, null, createInvoiceItemResult);
}
+
+ // Create the OrderAdjustmentBilling record
+ Map createOrderAdjustmentBillingContext = FastMap.newInstance();
+ createOrderAdjustmentBillingContext.put("orderAdjustmentId", adj.getString("orderAdjustmentId"));
+ createOrderAdjustmentBillingContext.put("invoiceId", invoiceId);
+ createOrderAdjustmentBillingContext.put("invoiceItemSeqId", invoiceItemSeqId);
+ createOrderAdjustmentBillingContext.put("amount", new Double(amount.doubleValue()));
+ createOrderAdjustmentBillingContext.put("userLogin", userLogin);
+
+ try {
+ Map createOrderAdjustmentBillingResult = dispatcher.runSync("createOrderAdjustmentBilling", createOrderAdjustmentBillingContext);
+ } catch( GenericServiceException e ) {
+ ServiceUtil.returnError(UtilProperties.getMessage(resource,"AccountingErrorCreatingOrderAdjustmentBillingFromOrder",locale), null, null, createOrderAdjustmentBillingContext);
+ }
+
}
amount.setScale(decimals, rounding);
adjAmount = amount;
@@ -2381,6 +2672,30 @@
errorMessageList.add("??unsuitable parameters passed...?? This message.... should never be shown\n");
errorMessageList.add("--Input parameters...InvoiceId:" + invoiceId + " invoiceItemSeqId:" + invoiceItemSeqId + " PaymentId:" + paymentId + " toPaymentId:" + toPaymentId + "\n paymentApplicationId:" + paymentApplicationId + " amountApplied:" + amountApplied);
return ServiceUtil.returnError(errorMessageList);
+ }
+
+ public static Map calculateInvoicedAdjustmentTotalBd(DispatchContext dctx, Map context) {
+ GenericDelegator delegator = dctx.getDelegator();
+ Locale locale = (Locale) context.get("locale");
+ GenericValue orderAdjustment = (GenericValue) context.get("orderAdjustment");
+ Map result = ServiceUtil.returnSuccess();
+
+ BigDecimal invoicedTotal = ZERO;
+ List invoicedAdjustments = null;
+ try {
+ invoicedAdjustments = delegator.findByAnd("OrderAdjustmentBilling", UtilMisc.toMap("orderAdjustmentId", orderAdjustment.getString("orderAdjustmentId")));
+ } catch( GenericEntityException e ) {
+ String errMsg = UtilProperties.getMessage(resource, "AccountingTroubleCallingCalculateInvoicedAdjustmentTotalService" + ": " + e.getMessage(), locale);
+ Debug.logError(e, errMsg, module);
+ return ServiceUtil.returnError(errMsg);
+ }
+ Iterator iait = invoicedAdjustments.iterator();
+ while (iait.hasNext()) {
+ GenericValue invoicedAdjustment = (GenericValue) iait.next();
+ invoicedTotal = invoicedTotal.add(invoicedAdjustment.getBigDecimal("amount").setScale(decimals, rounding));
+ }
+ result.put("invoicedTotal", invoicedTotal);
+ return result;
}
/**