List of usage examples for java.math BigDecimal multiply
public BigDecimal multiply(BigDecimal multiplicand)
(this × multiplicand)
, and whose scale is (this.scale() + multiplicand.scale()) . From source file:org.ofbiz.order.order.OrderServices.java
/** * Determines the total amount invoiced for a given order item over all invoices by totalling the item subtotal (via OrderItemBilling), * any adjustments for that item (via OrderAdjustmentBilling), and the item's share of any order-level adjustments (that calculated * by applying the percentage of the items total that the item represents to the order-level adjustments total (also via * OrderAdjustmentBilling). Also returns the quantity invoiced for the item over all invoices, to aid in prorating. * @param dctx DispatchContext//w w w .j av a 2s . co m * @param context Map * @return Map */ public static Map<String, Object> getOrderItemInvoicedAmountAndQuantity(DispatchContext dctx, Map<String, ? extends Object> context) { Delegator delegator = dctx.getDelegator(); Locale locale = (Locale) context.get("locale"); String orderId = (String) context.get("orderId"); String orderItemSeqId = (String) context.get("orderItemSeqId"); GenericValue orderHeader = null; GenericValue orderItemToCheck = null; BigDecimal orderItemTotalValue = ZERO; BigDecimal invoicedQuantity = ZERO; // Quantity invoiced for the target order item try { orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); if (UtilValidate.isEmpty(orderHeader)) { String errorMessage = UtilProperties.getMessage(resource_error, "OrderErrorOrderIdNotFound", context, locale); Debug.logError(errorMessage, module); return ServiceUtil.returnError(errorMessage); } orderItemToCheck = delegator.findByPrimaryKey("OrderItem", UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItemSeqId)); if (UtilValidate.isEmpty(orderItemToCheck)) { String errorMessage = UtilProperties.getMessage(resource_error, "OrderErrorOrderItemNotFound", context, locale); Debug.logError(errorMessage, module); return ServiceUtil.returnError(errorMessage); } BigDecimal orderItemsSubtotal = ZERO; // Aggregated value of order items, non-tax and non-shipping item-level adjustments BigDecimal invoicedTotal = ZERO; // Amount invoiced for the target order item BigDecimal itemAdjustments = ZERO; // Item-level tax- and shipping-adjustments // Aggregate the order items subtotal List<GenericValue> orderItems = orderHeader.getRelated("OrderItem", UtilMisc.toList("orderItemSeqId")); Iterator<GenericValue> oit = orderItems.iterator(); while (oit.hasNext()) { GenericValue orderItem = oit.next(); // Look at the orderItemBillings to discover the amount and quantity ever invoiced for this order item List<GenericValue> orderItemBillings = delegator.findByAnd("OrderItemBilling", UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItem.get("orderItemSeqId"))); Iterator<GenericValue> oibit = orderItemBillings.iterator(); while (oibit.hasNext()) { GenericValue orderItemBilling = oibit.next(); BigDecimal quantity = orderItemBilling.getBigDecimal("quantity"); BigDecimal amount = orderItemBilling.getBigDecimal("amount").setScale(orderDecimals, orderRounding); if (UtilValidate.isEmpty(invoicedQuantity) || UtilValidate.isEmpty(amount)) continue; // Add the item base amount to the subtotal orderItemsSubtotal = orderItemsSubtotal.add(quantity.multiply(amount)); // If the item is the target order item, add the invoiced quantity and amount to their respective totals if (orderItemSeqId.equals(orderItem.get("orderItemSeqId"))) { invoicedQuantity = invoicedQuantity.add(quantity); invoicedTotal = invoicedTotal.add(quantity.multiply(amount)); } } // Retrieve the adjustments for this item List<GenericValue> orderAdjustments = delegator.findByAnd("OrderAdjustment", UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItem.get("orderItemSeqId"))); Iterator<GenericValue> oait = orderAdjustments.iterator(); while (oait.hasNext()) { GenericValue orderAdjustment = oait.next(); String orderAdjustmentTypeId = orderAdjustment.getString("orderAdjustmentTypeId"); boolean includeInTax = orderAdjustment.getBoolean("includeInTax").booleanValue(); // Look at the orderAdjustmentBillings to discove the amount ever invoiced for this order adjustment List<GenericValue> orderAdjustmentBillings = delegator.findByAnd("OrderAdjustmentBilling", UtilMisc.toMap("orderAdjustmentId", orderAdjustment.get("orderAdjustmentId"))); Iterator<GenericValue> oabit = orderAdjustmentBillings.iterator(); while (oabit.hasNext()) { GenericValue orderAjustmentBilling = oabit.next(); BigDecimal amount = orderAjustmentBilling.getBigDecimal("amount").setScale(orderDecimals, orderRounding); if (UtilValidate.isEmpty(amount)) continue; if (includeInTax || "SALES_TAX".equals(orderAdjustmentTypeId) || "SHIPPING_CHARGES".equals(orderAdjustmentTypeId)) { if (orderItemSeqId.equals(orderItem.get("orderItemSeqId"))) { // Add tax- and shipping-adjustment amounts to the total adjustments for the target order item itemAdjustments = itemAdjustments.add(amount); } } else { // Add non-tax and non-shipping adjustment amounts to the order items subtotal orderItemsSubtotal = orderItemsSubtotal.add(amount); if (orderItemSeqId.equals(orderItem.get("orderItemSeqId"))) { // If the item is the target order item, add non-tax and non-shipping adjustment amounts to the invoiced total invoicedTotal = invoicedTotal.add(amount); } } } } } // Total the order-header-level adjustments for the order BigDecimal orderHeaderAdjustmentsTotalValue = ZERO; List<GenericValue> orderHeaderAdjustments = delegator.findByAnd("OrderAdjustment", UtilMisc.toMap("orderId", orderId, "orderItemSeqId", "_NA_")); Iterator<GenericValue> ohait = orderHeaderAdjustments.iterator(); while (ohait.hasNext()) { GenericValue orderHeaderAdjustment = ohait.next(); List<GenericValue> orderHeaderAdjustmentBillings = delegator.findByAnd("OrderAdjustmentBilling", UtilMisc.toMap("orderAdjustmentId", orderHeaderAdjustment.get("orderAdjustmentId"))); Iterator<GenericValue> ohabit = orderHeaderAdjustmentBillings.iterator(); while (ohabit.hasNext()) { GenericValue orderHeaderAdjustmentBilling = ohabit.next(); BigDecimal amount = orderHeaderAdjustmentBilling.getBigDecimal("amount").setScale(orderDecimals, orderRounding); if (UtilValidate.isEmpty(amount)) continue; orderHeaderAdjustmentsTotalValue = orderHeaderAdjustmentsTotalValue.add(amount); } } // How much of the order-level adjustments total does the target order item represent? The assumption is: the same // proportion of the adjustments as of the invoiced total for the item to the invoiced total for all items. These // figures don't take tax- and shipping- adjustments into account, so as to be in accordance with the code in InvoiceServices BigDecimal invoicedAmountProportion = ZERO; if (orderItemsSubtotal.signum() != 0) { invoicedAmountProportion = invoicedTotal.divide(orderItemsSubtotal, 5, orderRounding); } BigDecimal orderItemHeaderAjustmentAmount = orderHeaderAdjustmentsTotalValue .multiply(invoicedAmountProportion); orderItemTotalValue = invoicedTotal.add(orderItemHeaderAjustmentAmount); // Add back the tax- and shipping- item-level adjustments for the order item orderItemTotalValue = orderItemTotalValue.add(itemAdjustments); } catch (GenericEntityException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } Map<String, Object> result = ServiceUtil.returnSuccess(); result.put("invoicedAmount", orderItemTotalValue.setScale(orderDecimals, orderRounding)); result.put("invoicedQuantity", invoicedQuantity.setScale(orderDecimals, orderRounding)); return result; }
From source file:org.apache.ofbiz.accounting.invoice.InvoiceServices.java
public static Map<String, Object> createInvoiceFromReturn(DispatchContext dctx, Map<String, Object> context) { Delegator delegator = dctx.getDelegator(); LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); Locale locale = (Locale) context.get("locale"); String returnId = (String) context.get("returnId"); List<GenericValue> billItems = UtilGenerics.checkList(context.get("billItems")); String errorMsg = UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceForReturn", UtilMisc.toMap("returnId", returnId), locale); // List invoicesCreated = new ArrayList(); try {// w w w .j av a2s. c o m String invoiceTypeId; String description; // get the return header GenericValue returnHeader = EntityQuery.use(delegator).from("ReturnHeader").where("returnId", returnId) .queryOne(); if (returnHeader == null || returnHeader.get("returnHeaderTypeId") == null) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingReturnTypeCannotBeNull", locale)); } if (returnHeader.getString("returnHeaderTypeId").startsWith("CUSTOMER_")) { invoiceTypeId = "CUST_RTN_INVOICE"; description = "Return Invoice for Customer Return #" + returnId; } else { invoiceTypeId = "PURC_RTN_INVOICE"; description = "Return Invoice for Vendor Return #" + returnId; } List<GenericValue> returnItems = returnHeader.getRelated("ReturnItem", null, null, false); if (!returnItems.isEmpty()) { for (GenericValue returnItem : returnItems) { if ("RETURN_COMPLETED".equals(returnItem.getString("statusId"))) { GenericValue product = returnItem.getRelatedOne("Product", false); if (!ProductWorker.isPhysical(product)) { boolean isNonPhysicalItemToReturn = false; List<GenericValue> returnItemBillings = returnItem.getRelated("ReturnItemBilling", null, null, false); if (!returnItemBillings.isEmpty()) { GenericValue invoice = EntityUtil.getFirst(returnItemBillings) .getRelatedOne("Invoice", false); if ("INVOICE_CANCELLED".equals(invoice.getString("statusId"))) { isNonPhysicalItemToReturn = true; } } else { isNonPhysicalItemToReturn = true; } if (isNonPhysicalItemToReturn) { if (UtilValidate.isEmpty(billItems)) { billItems = new ArrayList<GenericValue>(); } billItems.add(returnItem); } } } } } Map<String, Object> results = ServiceUtil.returnSuccess(); if (UtilValidate.isNotEmpty(billItems)) { // set the invoice data Map<String, Object> input = UtilMisc.<String, Object>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", description); input.put("billingAccountId", returnHeader.get("billingAccountId")); input.put("userLogin", userLogin); // call the service to create the invoice Map<String, Object> serviceResults = dispatcher.runSync("createInvoice", input); if (ServiceUtil.isError(serviceResults)) { return ServiceUtil.returnError(errorMsg, null, null, serviceResults); } String invoiceId = (String) serviceResults.get("invoiceId"); // keep track of the invoice total vs the promised return total (how much the customer promised to return) BigDecimal invoiceTotal = ZERO; BigDecimal promisedTotal = ZERO; // 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 (GenericValue item : billItems) { boolean shipmentReceiptFound = false; boolean itemIssuanceFound = false; GenericValue returnItem = null; BigDecimal quantity = BigDecimal.ZERO; if ("ShipmentReceipt".equals(item.getEntityName())) { shipmentReceiptFound = true; } else if ("ItemIssuance".equals(item.getEntityName())) { itemIssuanceFound = true; } else if ("ReturnItem".equals(item.getEntityName())) { quantity = item.getBigDecimal("returnQuantity"); returnItem = item; } else { Debug.logError("Unexpected entity " + item + " of type " + item.getEntityName(), module); } // we need the related return item and product if (shipmentReceiptFound) { returnItem = item.getRelatedOne("ReturnItem", true); } else if (itemIssuanceFound) { GenericValue shipmentItem = item.getRelatedOne("ShipmentItem", true); GenericValue returnItemShipment = EntityUtil .getFirst(shipmentItem.getRelated("ReturnItemShipment", null, null, false)); returnItem = returnItemShipment.getRelatedOne("ReturnItem", true); } if (returnItem == null) continue; // Just to prevent NPE GenericValue product = returnItem.getRelatedOne("Product", true); // 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, invoiceTypeId, null); if (invoiceItemTypeId == null) { return ServiceUtil.returnError(errorMsg + UtilProperties.getMessage(resource, "AccountingNoKnownInvoiceItemTypeReturnItemType", UtilMisc.toMap("returnItemTypeId", returnItem.getString("returnItemTypeId")), locale)); } if (shipmentReceiptFound) { quantity = item.getBigDecimal("quantityAccepted"); } else if (itemIssuanceFound) { quantity = item.getBigDecimal("quantity"); } // create the invoice item for this shipment receipt 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")); input.put("productId", returnItem.get("productId")); input.put("taxableFlag", product.get("taxable")); input.put("description", returnItem.get("description")); // TODO: what about the productFeatureId? input.put("userLogin", userLogin); serviceResults = dispatcher.runSync("createInvoiceItem", input); if (ServiceUtil.isError(serviceResults)) { return ServiceUtil.returnError(errorMsg, null, null, serviceResults); } // copy the return item information into ReturnItemBilling 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("quantity", quantity); input.put("amount", returnItem.get("returnPrice")); 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 " + quantity + " for shipment [" + item.getString("shipmentId") + ":" + item.getString("shipmentItemSeqId") + "]", module); } String parentInvoiceItemSeqId = invoiceItemSeqId; // increment the seqId counter after creating the invoice item and return item billing invoiceItemSeqNum += 1; 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 cancelQuantity = ZERO; if (shipmentReceiptFound) { cancelQuantity = item.getBigDecimal("quantityRejected"); } else if (itemIssuanceFound) { cancelQuantity = item.getBigDecimal("cancelQuantity"); } if (cancelQuantity == null) cancelQuantity = ZERO; BigDecimal actualAmount = returnPrice.multiply(quantity).setScale(DECIMALS, ROUNDING); BigDecimal promisedAmount = returnPrice.multiply(quantity.add(cancelQuantity)) .setScale(DECIMALS, ROUNDING); invoiceTotal = invoiceTotal.add(actualAmount).setScale(DECIMALS, ROUNDING); promisedTotal = promisedTotal.add(promisedAmount).setScale(DECIMALS, ROUNDING); // for each adjustment related to this ReturnItem, create a separate invoice item List<GenericValue> adjustments = returnItem.getRelated("ReturnAdjustment", null, null, true); for (GenericValue adjustment : adjustments) { if (adjustment.get("amount") == null) { Debug.logWarning("Return adjustment [" + adjustment.get("returnAdjustmentId") + "] has null amount and will be skipped", module); continue; } // determine invoice item type from the return item type 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)); } // prorate the adjustment amount by the returned amount; do not round ratio BigDecimal ratio = quantity.divide(returnItem.getBigDecimal("returnQuantity"), 100, ROUNDING); BigDecimal amount = adjustment.getBigDecimal("amount"); amount = amount.multiply(ratio).setScale(DECIMALS, ROUNDING); if (Debug.verboseOn()) { Debug.logVerbose("Creating Invoice Item with amount " + adjustment.getBigDecimal("amount") + " prorated to " + amount + " for return adjustment [" + adjustment.getString("returnAdjustmentId") + "]", module); } // prepare invoice item data for this adjustment input = UtilMisc.toMap("invoiceId", invoiceId, "invoiceItemTypeId", invoiceItemTypeId, "quantity", BigDecimal.ONE); input.put("amount", amount); input.put("invoiceItemSeqId", "" + invoiceItemSeqId); // turn the int into a string with ("" + int) hack input.put("productId", returnItem.get("productId")); input.put("description", adjustment.get("description")); input.put("overrideGlAccountId", adjustment.get("overrideGlAccountId")); input.put("parentInvoiceId", invoiceId); input.put("parentInvoiceItemSeqId", parentInvoiceItemSeqId); input.put("taxAuthPartyId", adjustment.get("taxAuthPartyId")); input.put("taxAuthGeoId", adjustment.get("taxAuthGeoId")); input.put("userLogin", userLogin); // only set taxable flag when the adjustment is not a tax // TODO: Note that we use the value of Product.taxable here. This is not an ideal solution. Instead, use returnAdjustment.includeInTax if (adjustment.get("returnAdjustmentTypeId").equals("RET_SALES_TAX_ADJ")) { input.put("taxableFlag", "N"); } // create the invoice item serviceResults = dispatcher.runSync("createInvoiceItem", input); if (ServiceUtil.isError(serviceResults)) { return ServiceUtil.returnError(errorMsg, null, null, serviceResults); } // increment the seqId counter invoiceItemSeqNum += 1; invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, INVOICE_ITEM_SEQUENCE_ID_DIGITS); // keep a running total (promised adjustment in this case is the same as the invoice adjustment) invoiceTotal = invoiceTotal.add(amount).setScale(DECIMALS, ROUNDING); promisedTotal = promisedTotal.add(amount).setScale(DECIMALS, ROUNDING); } } // ratio of the invoice total to the promised total so far or zero if the amounts were zero BigDecimal actualToPromisedRatio = ZERO; if (invoiceTotal.signum() != 0) { actualToPromisedRatio = invoiceTotal.divide(promisedTotal, 100, ROUNDING); // do not round ratio } // loop through return-wide adjustments and create invoice items for each List<GenericValue> adjustments = returnHeader.getRelated("ReturnAdjustment", UtilMisc.toMap("returnItemSeqId", "_NA_"), null, true); for (GenericValue adjustment : adjustments) { // determine invoice item type from the return item type 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)); } // prorate the adjustment amount by the actual to promised ratio BigDecimal amount = adjustment.getBigDecimal("amount").multiply(actualToPromisedRatio) .setScale(DECIMALS, ROUNDING); if (Debug.verboseOn()) { Debug.logVerbose("Creating Invoice Item with amount " + adjustment.getBigDecimal("amount") + " prorated to " + amount + " for return adjustment [" + adjustment.getString("returnAdjustmentId") + "]", module); } // prepare the invoice item for the return-wide adjustment input = UtilMisc.toMap("invoiceId", invoiceId, "invoiceItemTypeId", invoiceItemTypeId, "quantity", BigDecimal.ONE); input.put("amount", amount); input.put("invoiceItemSeqId", "" + invoiceItemSeqId); // turn the int into a string with ("" + int) hack input.put("description", adjustment.get("description")); input.put("overrideGlAccountId", adjustment.get("overrideGlAccountId")); input.put("taxAuthPartyId", adjustment.get("taxAuthPartyId")); input.put("taxAuthGeoId", adjustment.get("taxAuthGeoId")); input.put("userLogin", userLogin); // XXX TODO Note: we need to implement ReturnAdjustment.includeInTax for this to work properly input.put("taxableFlag", adjustment.get("includeInTax")); // create the invoice item serviceResults = dispatcher.runSync("createInvoiceItem", input); if (ServiceUtil.isError(serviceResults)) { return ServiceUtil.returnError(errorMsg, null, null, serviceResults); } // increment the seqId counter invoiceItemSeqNum += 1; invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, INVOICE_ITEM_SEQUENCE_ID_DIGITS); } // Set the invoice to READY serviceResults = dispatcher.runSync("setInvoiceStatus", UtilMisc.<String, Object>toMap("invoiceId", invoiceId, "statusId", "INVOICE_READY", "userLogin", userLogin)); if (ServiceUtil.isError(serviceResults)) { return ServiceUtil.returnError(errorMsg, null, null, serviceResults); } // return the invoiceId results.put("invoiceId", invoiceId); } return results; } catch (GenericServiceException e) { Debug.logError(e, errorMsg + e.getMessage(), module); return ServiceUtil.returnError(errorMsg + e.getMessage()); } catch (GenericEntityException e) { Debug.logError(e, errorMsg + e.getMessage(), module); return ServiceUtil.returnError(errorMsg + e.getMessage()); } }
From source file:org.apache.ofbiz.accounting.invoice.InvoiceServices.java
public static Map<String, Object> createInvoiceForOrder(DispatchContext dctx, Map<String, Object> context) { Delegator delegator = dctx.getDelegator(); LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); Locale locale = (Locale) context.get("locale"); if (DECIMALS == -1 || ROUNDING == -1) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingAritmeticPropertiesNotConfigured", locale)); }//from w ww. j av a2 s . c o m String orderId = (String) context.get("orderId"); List<GenericValue> billItems = UtilGenerics.checkList(context.get("billItems")); String invoiceId = (String) context.get("invoiceId"); if (UtilValidate.isEmpty(billItems)) { Debug.logVerbose("No order items to invoice; not creating invoice; returning success", module); return ServiceUtil .returnSuccess(UtilProperties.getMessage(resource, "AccountingNoOrderItemsToInvoice", locale)); } try { GenericValue orderHeader = EntityQuery.use(delegator).from("OrderHeader").where("orderId", orderId) .queryOne(); if (orderHeader == null) { return ServiceUtil .returnError(UtilProperties.getMessage(resource, "AccountingNoOrderHeader", locale)); } // figure out the invoice type String invoiceType = null; String orderType = orderHeader.getString("orderTypeId"); if (orderType.equals("SALES_ORDER")) { invoiceType = "SALES_INVOICE"; } else if (orderType.equals("PURCHASE_ORDER")) { invoiceType = "PURCHASE_INVOICE"; } // Set the precision depending on the type of invoice int invoiceTypeDecimals = UtilNumber.getBigDecimalScale("invoice." + invoiceType + ".decimals"); if (invoiceTypeDecimals == -1) invoiceTypeDecimals = DECIMALS; // Make an order read helper from the order OrderReadHelper orh = new OrderReadHelper(orderHeader); // get the product store GenericValue productStore = orh.getProductStore(); // get the shipping adjustment mode (Y = Pro-Rate; N = First-Invoice) String prorateShipping = productStore != null ? productStore.getString("prorateShipping") : "Y"; if (prorateShipping == null) { prorateShipping = "Y"; } // get the billing parties String billToCustomerPartyId = orh.getBillToParty().getString("partyId"); String billFromVendorPartyId = orh.getBillFromParty().getString("partyId"); // get some price totals BigDecimal shippableAmount = orh.getShippableTotal(null); BigDecimal shippableQuantity = orh.getShippableQuantity(null); BigDecimal orderSubTotal = orh.getOrderItemsSubTotal(); BigDecimal orderQuantity = orh.getTotalOrderItemsQuantity(); // these variables are for pro-rating order amounts across invoices, so they should not be rounded off for maximum accuracy BigDecimal invoiceShipProRateAmount = ZERO; BigDecimal invoiceShippableQuantity = ZERO; BigDecimal invoiceSubTotal = ZERO; BigDecimal invoiceQuantity = ZERO; GenericValue billingAccount = orderHeader.getRelatedOne("BillingAccount", false); String billingAccountId = billingAccount != null ? billingAccount.getString("billingAccountId") : null; Timestamp invoiceDate = (Timestamp) context.get("eventDate"); if (UtilValidate.isEmpty(invoiceDate)) { // TODO: ideally this should be the same time as when a shipment is sent and be passed in as a parameter invoiceDate = UtilDateTime.nowTimestamp(); } // TODO: perhaps consider billing account net days term as well? Long orderTermNetDays = orh.getOrderTermNetDays(); Timestamp dueDate = null; if (orderTermNetDays != null) { dueDate = UtilDateTime.getDayEnd(invoiceDate, orderTermNetDays); } // create the invoice record if (UtilValidate.isEmpty(invoiceId)) { Map<String, Object> createInvoiceContext = new HashMap<String, Object>(); createInvoiceContext.put("partyId", billToCustomerPartyId); createInvoiceContext.put("partyIdFrom", billFromVendorPartyId); createInvoiceContext.put("billingAccountId", billingAccountId); createInvoiceContext.put("invoiceDate", invoiceDate); createInvoiceContext.put("dueDate", dueDate); createInvoiceContext.put("invoiceTypeId", invoiceType); // start with INVOICE_IN_PROCESS, in the INVOICE_READY we can't change the invoice (or shouldn't be able to...) createInvoiceContext.put("statusId", "INVOICE_IN_PROCESS"); createInvoiceContext.put("currencyUomId", orderHeader.getString("currencyUom")); createInvoiceContext.put("userLogin", userLogin); // store the invoice first Map<String, Object> createInvoiceResult = dispatcher.runSync("createInvoice", createInvoiceContext); if (ServiceUtil.isError(createInvoiceResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceFromOrder", locale), null, null, createInvoiceResult); } // call service, not direct entity op: delegator.create(invoice); invoiceId = (String) createInvoiceResult.get("invoiceId"); } // order roles to invoice roles List<GenericValue> orderRoles = orderHeader.getRelated("OrderRole", null, null, false); Map<String, Object> createInvoiceRoleContext = new HashMap<String, Object>(); createInvoiceRoleContext.put("invoiceId", invoiceId); createInvoiceRoleContext.put("userLogin", userLogin); for (GenericValue orderRole : orderRoles) { createInvoiceRoleContext.put("partyId", orderRole.getString("partyId")); createInvoiceRoleContext.put("roleTypeId", orderRole.getString("roleTypeId")); Map<String, Object> createInvoiceRoleResult = dispatcher.runSync("createInvoiceRole", createInvoiceRoleContext); if (ServiceUtil.isError(createInvoiceRoleResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceFromOrder", locale), null, null, createInvoiceRoleResult); } } // order terms to invoice terms. // TODO: it might be nice to filter OrderTerms to only copy over financial terms. List<GenericValue> orderTerms = orh.getOrderTerms(); createInvoiceTerms(delegator, dispatcher, invoiceId, orderTerms, userLogin, locale); // billing accounts // List billingAccountTerms = null; // for billing accounts we will use related information if (billingAccount != null) { /* * jacopoc: billing account terms were already copied as order terms * when the order was created. // get the billing account terms billingAccountTerms = billingAccount.getRelated("BillingAccountTerm", null, null, false); // set the invoice terms as defined for the billing account createInvoiceTerms(delegator, dispatcher, invoiceId, billingAccountTerms, userLogin, locale); */ // set the invoice bill_to_customer from the billing account List<GenericValue> billToRoles = billingAccount.getRelated("BillingAccountRole", UtilMisc.toMap("roleTypeId", "BILL_TO_CUSTOMER"), null, false); for (GenericValue billToRole : billToRoles) { if (!(billToRole.getString("partyId").equals(billToCustomerPartyId))) { createInvoiceRoleContext = UtilMisc.toMap("invoiceId", invoiceId, "partyId", billToRole.get("partyId"), "roleTypeId", "BILL_TO_CUSTOMER", "userLogin", userLogin); Map<String, Object> createInvoiceRoleResult = dispatcher.runSync("createInvoiceRole", createInvoiceRoleContext); if (ServiceUtil.isError(createInvoiceRoleResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceRoleFromOrder", locale), null, null, createInvoiceRoleResult); } } } // set the bill-to contact mech as the contact mech of the billing account if (UtilValidate.isNotEmpty(billingAccount.getString("contactMechId"))) { Map<String, Object> createBillToContactMechContext = UtilMisc.toMap("invoiceId", invoiceId, "contactMechId", billingAccount.getString("contactMechId"), "contactMechPurposeTypeId", "BILLING_LOCATION", "userLogin", userLogin); Map<String, Object> createBillToContactMechResult = dispatcher .runSync("createInvoiceContactMech", createBillToContactMechContext); if (ServiceUtil.isError(createBillToContactMechResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceContactMechFromOrder", locale), null, null, createBillToContactMechResult); } } } else { List<GenericValue> billingLocations = orh.getBillingLocations(); if (UtilValidate.isNotEmpty(billingLocations)) { for (GenericValue ocm : billingLocations) { Map<String, Object> createBillToContactMechContext = UtilMisc.toMap("invoiceId", invoiceId, "contactMechId", ocm.getString("contactMechId"), "contactMechPurposeTypeId", "BILLING_LOCATION", "userLogin", userLogin); Map<String, Object> createBillToContactMechResult = dispatcher .runSync("createInvoiceContactMech", createBillToContactMechContext); if (ServiceUtil.isError(createBillToContactMechResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceContactMechFromOrder", locale), null, null, createBillToContactMechResult); } } } else { Debug.logWarning("No billing locations found for order [" + orderId + "] and none were created for Invoice [" + invoiceId + "]", module); } } // get a list of the payment method types //DEJ20050705 doesn't appear to be used: List paymentPreferences = orderHeader.getRelated("OrderPaymentPreference", null, null, false); // create the bill-from (or pay-to) contact mech as the primary PAYMENT_LOCATION of the party from the store GenericValue payToAddress = null; if (invoiceType.equals("PURCHASE_INVOICE")) { // for purchase orders, the pay to address is the BILLING_LOCATION of the vendor GenericValue billFromVendor = orh.getPartyFromRole("BILL_FROM_VENDOR"); if (billFromVendor != null) { List<GenericValue> billingContactMechs = billFromVendor.getRelatedOne("Party", false) .getRelated("PartyContactMechPurpose", UtilMisc.toMap("contactMechPurposeTypeId", "BILLING_LOCATION"), null, false); if (UtilValidate.isNotEmpty(billingContactMechs)) { payToAddress = EntityUtil.getFirst(billingContactMechs); } } } else { // for sales orders, it is the payment address on file for the store payToAddress = PaymentWorker.getPaymentAddress(delegator, productStore.getString("payToPartyId")); } if (payToAddress != null) { Map<String, Object> createPayToContactMechContext = UtilMisc.toMap("invoiceId", invoiceId, "contactMechId", payToAddress.getString("contactMechId"), "contactMechPurposeTypeId", "PAYMENT_LOCATION", "userLogin", userLogin); Map<String, Object> createPayToContactMechResult = dispatcher.runSync("createInvoiceContactMech", createPayToContactMechContext); if (ServiceUtil.isError(createPayToContactMechResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceContactMechFromOrder", locale), null, null, createPayToContactMechResult); } } // sequence for items - all OrderItems or InventoryReservations + all Adjustments int invoiceItemSeqNum = 1; String invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, INVOICE_ITEM_SEQUENCE_ID_DIGITS); // create the item records for (GenericValue currentValue : billItems) { GenericValue itemIssuance = null; GenericValue orderItem = null; GenericValue shipmentReceipt = null; if ("ItemIssuance".equals(currentValue.getEntityName())) { itemIssuance = currentValue; } else if ("OrderItem".equals(currentValue.getEntityName())) { orderItem = currentValue; } else if ("ShipmentReceipt".equals(currentValue.getEntityName())) { shipmentReceipt = currentValue; } else { Debug.logError("Unexpected entity " + currentValue + " of type " + currentValue.getEntityName(), module); } if (orderItem == null && itemIssuance != null) { orderItem = itemIssuance.getRelatedOne("OrderItem", false); } else if ((orderItem == null) && (shipmentReceipt != null)) { orderItem = shipmentReceipt.getRelatedOne("OrderItem", false); } else if ((orderItem == null) && (itemIssuance == null) && (shipmentReceipt == null)) { Debug.logError( "Cannot create invoice when orderItem, itemIssuance, and shipmentReceipt are all null", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingIllegalValuesPassedToCreateInvoiceService", locale)); } GenericValue product = null; if (orderItem.get("productId") != null) { product = orderItem.getRelatedOne("Product", false); } // get some quantities BigDecimal billingQuantity = null; if (itemIssuance != null) { billingQuantity = itemIssuance.getBigDecimal("quantity"); BigDecimal cancelQty = itemIssuance.getBigDecimal("cancelQuantity"); if (cancelQty == null) { cancelQty = ZERO; } billingQuantity = billingQuantity.subtract(cancelQty).setScale(DECIMALS, ROUNDING); } else if (shipmentReceipt != null) { billingQuantity = shipmentReceipt.getBigDecimal("quantityAccepted"); } else { BigDecimal orderedQuantity = OrderReadHelper.getOrderItemQuantity(orderItem); BigDecimal invoicedQuantity = OrderReadHelper.getOrderItemInvoicedQuantity(orderItem); billingQuantity = orderedQuantity.subtract(invoicedQuantity); if (billingQuantity.compareTo(ZERO) < 0) { billingQuantity = ZERO; } } if (billingQuantity == null) billingQuantity = ZERO; // check if shipping applies to this item. Shipping is calculated for sales invoices, not purchase invoices. boolean shippingApplies = false; if ((product != null) && (ProductWorker.shippingApplies(product)) && (invoiceType.equals("SALES_INVOICE"))) { shippingApplies = true; } BigDecimal billingAmount = BigDecimal.ZERO; GenericValue OrderAdjustment = EntityUtil.getFirst(orderItem.getRelated("OrderAdjustment", UtilMisc.toMap("orderAdjustmentTypeId", "VAT_TAX"), null, false)); /* Apply formula to get actual product price to set amount in invoice item Formula is: productPrice = (productPriceWithTax.multiply(100)) / (orderAdj sourcePercentage + 100)) product price = (43*100) / (20+100) = 35.83 (Here product price is 43 with VAT) */ if (UtilValidate.isNotEmpty(OrderAdjustment) && (OrderAdjustment.getBigDecimal("amount").signum() == 0) && UtilValidate.isNotEmpty(OrderAdjustment.getBigDecimal("amountAlreadyIncluded")) && OrderAdjustment.getBigDecimal("amountAlreadyIncluded").signum() != 0) { BigDecimal sourcePercentageTotal = OrderAdjustment.getBigDecimal("sourcePercentage") .add(new BigDecimal(100)); billingAmount = orderItem.getBigDecimal("unitPrice") .divide(sourcePercentageTotal, 100, ROUNDING).multiply(new BigDecimal(100)) .setScale(invoiceTypeDecimals, ROUNDING); } else { billingAmount = orderItem.getBigDecimal("unitPrice").setScale(invoiceTypeDecimals, ROUNDING); } Map<String, Object> createInvoiceItemContext = new HashMap<String, Object>(); createInvoiceItemContext.put("invoiceId", invoiceId); createInvoiceItemContext.put("invoiceItemSeqId", invoiceItemSeqId); createInvoiceItemContext.put("invoiceItemTypeId", getInvoiceItemType(delegator, (orderItem.getString("orderItemTypeId")), (product == null ? null : product.getString("productTypeId")), invoiceType, "INV_FPROD_ITEM")); createInvoiceItemContext.put("description", orderItem.get("itemDescription")); createInvoiceItemContext.put("quantity", billingQuantity); createInvoiceItemContext.put("amount", billingAmount); createInvoiceItemContext.put("productId", orderItem.get("productId")); createInvoiceItemContext.put("productFeatureId", orderItem.get("productFeatureId")); createInvoiceItemContext.put("overrideGlAccountId", orderItem.get("overrideGlAccountId")); createInvoiceItemContext.put("userLogin", userLogin); String itemIssuanceId = null; if (itemIssuance != null && itemIssuance.get("inventoryItemId") != null) { itemIssuanceId = itemIssuance.getString("itemIssuanceId"); createInvoiceItemContext.put("inventoryItemId", itemIssuance.get("inventoryItemId")); } // similarly, tax only for purchase invoices if ((product != null) && (invoiceType.equals("SALES_INVOICE"))) { createInvoiceItemContext.put("taxableFlag", product.get("taxable")); } Map<String, Object> createInvoiceItemResult = dispatcher.runSync("createInvoiceItem", createInvoiceItemContext); if (ServiceUtil.isError(createInvoiceItemResult)) { return ServiceUtil .returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceItemFromOrder", locale), null, null, createInvoiceItemResult); } // this item total BigDecimal thisAmount = billingAmount.multiply(billingQuantity).setScale(invoiceTypeDecimals, ROUNDING); // add to the ship amount only if it applies to this item if (shippingApplies) { invoiceShipProRateAmount = invoiceShipProRateAmount.add(thisAmount) .setScale(invoiceTypeDecimals, ROUNDING); invoiceShippableQuantity = invoiceQuantity.add(billingQuantity).setScale(invoiceTypeDecimals, ROUNDING); } // increment the invoice subtotal invoiceSubTotal = invoiceSubTotal.add(thisAmount).setScale(100, ROUNDING); // increment the invoice quantity invoiceQuantity = invoiceQuantity.add(billingQuantity).setScale(invoiceTypeDecimals, ROUNDING); // create the OrderItemBilling record Map<String, Object> createOrderItemBillingContext = new HashMap<String, Object>(); createOrderItemBillingContext.put("invoiceId", invoiceId); createOrderItemBillingContext.put("invoiceItemSeqId", invoiceItemSeqId); createOrderItemBillingContext.put("orderId", orderItem.get("orderId")); createOrderItemBillingContext.put("orderItemSeqId", orderItem.get("orderItemSeqId")); createOrderItemBillingContext.put("itemIssuanceId", itemIssuanceId); createOrderItemBillingContext.put("quantity", billingQuantity); createOrderItemBillingContext.put("amount", billingAmount); createOrderItemBillingContext.put("userLogin", userLogin); if ((shipmentReceipt != null) && (shipmentReceipt.getString("receiptId") != null)) { createOrderItemBillingContext.put("shipmentReceiptId", shipmentReceipt.getString("receiptId")); } Map<String, Object> createOrderItemBillingResult = dispatcher.runSync("createOrderItemBilling", createOrderItemBillingContext); if (ServiceUtil.isError(createOrderItemBillingResult)) { return ServiceUtil .returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingOrderItemBillingFromOrder", locale), null, null, createOrderItemBillingResult); } if ("ItemIssuance".equals(currentValue.getEntityName())) { /* Find ShipmentItemBilling based on shipmentId, shipmentItemSeqId, invoiceId, invoiceItemSeqId as because if any order item has multiple quantity and reserved by multiple inventories then there will be multiple invoice items. In that case ShipmentItemBilling was creating only for one invoice item. Fixed under OFBIZ-6806. */ List<GenericValue> shipmentItemBillings = EntityQuery.use(delegator).from("ShipmentItemBilling") .where("shipmentId", currentValue.get("shipmentId"), "shipmentItemSeqId", currentValue.get("shipmentItemSeqId"), "invoiceId", invoiceId, "invoiceItemSeqId", invoiceItemSeqId) .queryList(); if (UtilValidate.isEmpty(shipmentItemBillings)) { // create the ShipmentItemBilling record GenericValue shipmentItemBilling = delegator.makeValue("ShipmentItemBilling", UtilMisc.toMap("invoiceId", invoiceId, "invoiceItemSeqId", invoiceItemSeqId)); shipmentItemBilling.put("shipmentId", currentValue.get("shipmentId")); shipmentItemBilling.put("shipmentItemSeqId", currentValue.get("shipmentItemSeqId")); shipmentItemBilling.create(); } } String parentInvoiceItemSeqId = invoiceItemSeqId; // increment the counter invoiceItemSeqNum++; invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, INVOICE_ITEM_SEQUENCE_ID_DIGITS); // Get the original order item from the DB, in case the quantity has been overridden GenericValue originalOrderItem = EntityQuery.use(delegator).from("OrderItem") .where("orderId", orderId, "orderItemSeqId", orderItem.get("orderItemSeqId")).queryOne(); // create the item adjustment as line items List<GenericValue> itemAdjustments = OrderReadHelper.getOrderItemAdjustmentList(orderItem, orh.getAdjustments()); for (GenericValue adj : itemAdjustments) { // Check against OrderAdjustmentBilling to see how much of this adjustment has already been invoiced BigDecimal adjAlreadyInvoicedAmount = null; try { Map<String, Object> checkResult = dispatcher.runSync("calculateInvoicedAdjustmentTotal", UtilMisc.toMap("orderAdjustment", adj)); adjAlreadyInvoicedAmount = (BigDecimal) checkResult.get("invoicedTotal"); } catch (GenericServiceException e) { Debug.logError(e, "Accounting trouble calling calculateInvoicedAdjustmentTotal service", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingTroubleCallingCalculateInvoicedAdjustmentTotalService", locale)); } // if (adj.get("amount") == null) { TODO check usage with webPos. Was: fix a bug coming from POS in case of use of a discount (on item(s) or sale, item(s) here) and a cash amount higher than total (hence issuing change) // continue; // } // Set adjustment amount as amountAlreadyIncluded to continue invoice item creation process Boolean isTaxIncludedInPrice = adj.getString("orderAdjustmentTypeId").equals("VAT_TAX") && UtilValidate.isNotEmpty(adj.getBigDecimal("amountAlreadyIncluded")) && adj.getBigDecimal("amountAlreadyIncluded").signum() != 0; if ((adj.getBigDecimal("amount").signum() == 0) && isTaxIncludedInPrice) { adj.set("amount", adj.getBigDecimal("amountAlreadyIncluded")); } // 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(invoiceTypeDecimals, ROUNDING).abs()) > 0) { continue; } BigDecimal originalOrderItemQuantity = OrderReadHelper.getOrderItemQuantity(originalOrderItem); BigDecimal amount = ZERO; if (originalOrderItemQuantity.signum() != 0) { if (adj.get("amount") != null) { if ("PROMOTION_ADJUSTMENT".equals(adj.getString("orderAdjustmentTypeId")) && adj.get("productPromoId") != null) { /* Find negative amountAlreadyIncluded in OrderAdjustment to subtract it from discounted amount. As we stored negative sales tax amount in order adjustment for discounted item. */ List<EntityExpr> exprs = UtilMisc.toList( EntityCondition.makeCondition("orderId", EntityOperator.EQUALS, orderItem.getString("orderId")), EntityCondition.makeCondition("orderItemSeqId", EntityOperator.EQUALS, orderItem.getString("orderItemSeqId")), EntityCondition.makeCondition("orderAdjustmentTypeId", EntityOperator.EQUALS, "VAT_TAX"), EntityCondition.makeCondition("amountAlreadyIncluded", EntityOperator.LESS_THAN, BigDecimal.ZERO)); EntityCondition andCondition = EntityCondition.makeCondition(exprs, EntityOperator.AND); GenericValue orderAdjustment = EntityUtil.getFirst(delegator .findList("OrderAdjustment", andCondition, null, null, null, false)); if (UtilValidate.isNotEmpty(orderAdjustment)) { amount = adj.getBigDecimal("amount") .subtract(orderAdjustment.getBigDecimal("amountAlreadyIncluded")) .setScale(100, ROUNDING); } else { amount = adj.getBigDecimal("amount"); } } else { // pro-rate the amount // set decimals = 100 means we don't round this intermediate value, which is very important if (isTaxIncludedInPrice) { BigDecimal priceWithTax = originalOrderItem.getBigDecimal("unitPrice"); // Get tax included in item price amount = priceWithTax.subtract(billingAmount); amount = amount.multiply(billingQuantity); // get adjustment amount /* Get tax amount of other invoice and calculate remaining amount need to store in invoice item(Handle case of of partial shipment and promotional item) to adjust tax amount in invoice item. */ BigDecimal otherInvoiceTaxAmount = BigDecimal.ZERO; GenericValue orderAdjBilling = EntityUtil.getFirst(delegator.findByAnd( "OrderAdjustmentBilling", UtilMisc.toMap("orderAdjustmentId", adj.getString("orderAdjustmentId")), null, false)); if (UtilValidate.isNotEmpty(orderAdjBilling)) { List<GenericValue> invoiceItems = delegator.findByAnd("InvoiceItem", UtilMisc.toMap("invoiceId", orderAdjBilling.getString("invoiceId"), "invoiceItemTypeId", "ITM_SALES_TAX", "productId", originalOrderItem.getString("productId")), null, isTaxIncludedInPrice); for (GenericValue invoiceItem : invoiceItems) { otherInvoiceTaxAmount = otherInvoiceTaxAmount .add(invoiceItem.getBigDecimal("amount")); } if (otherInvoiceTaxAmount.compareTo(BigDecimal.ZERO) > 0) { BigDecimal remainingAmount = adj.getBigDecimal("amountAlreadyIncluded") .subtract(otherInvoiceTaxAmount); amount = amount.min(remainingAmount); } } amount = amount.min(adj.getBigDecimal("amountAlreadyIncluded")).setScale(100, ROUNDING); } else { amount = adj.getBigDecimal("amount").divide(originalOrderItemQuantity, 100, ROUNDING); amount = amount.multiply(billingQuantity); } } // Tax needs to be rounded differently from other order adjustments if (adj.getString("orderAdjustmentTypeId").equals("SALES_TAX")) { amount = amount.setScale(TAX_DECIMALS, TAX_ROUNDING); } else { amount = amount.setScale(invoiceTypeDecimals, ROUNDING); } } else if (adj.get("sourcePercentage") != null) { // pro-rate the amount // set decimals = 100 means we don't round this intermediate value, which is very important BigDecimal percent = adj.getBigDecimal("sourcePercentage"); percent = percent.divide(new BigDecimal(100), 100, ROUNDING); amount = billingAmount.multiply(percent); amount = amount.divide(originalOrderItemQuantity, 100, ROUNDING); amount = amount.multiply(billingQuantity); amount = amount.setScale(invoiceTypeDecimals, ROUNDING); } } if (amount.signum() != 0) { Map<String, Object> createInvoiceItemAdjContext = new HashMap<String, Object>(); createInvoiceItemAdjContext.put("invoiceId", invoiceId); createInvoiceItemAdjContext.put("invoiceItemSeqId", invoiceItemSeqId); createInvoiceItemAdjContext.put("invoiceItemTypeId", getInvoiceItemType(delegator, adj.getString("orderAdjustmentTypeId"), null, invoiceType, "INVOICE_ITM_ADJ")); createInvoiceItemAdjContext.put("quantity", BigDecimal.ONE); createInvoiceItemAdjContext.put("amount", amount); createInvoiceItemAdjContext.put("productId", orderItem.get("productId")); createInvoiceItemAdjContext.put("productFeatureId", orderItem.get("productFeatureId")); createInvoiceItemAdjContext.put("overrideGlAccountId", adj.get("overrideGlAccountId")); createInvoiceItemAdjContext.put("parentInvoiceId", invoiceId); createInvoiceItemAdjContext.put("parentInvoiceItemSeqId", parentInvoiceItemSeqId); createInvoiceItemAdjContext.put("userLogin", userLogin); createInvoiceItemAdjContext.put("taxAuthPartyId", adj.get("taxAuthPartyId")); createInvoiceItemAdjContext.put("taxAuthGeoId", adj.get("taxAuthGeoId")); createInvoiceItemAdjContext.put("taxAuthorityRateSeqId", adj.get("taxAuthorityRateSeqId")); // some adjustments fill out the comments field instead String description = (UtilValidate.isEmpty(adj.getString("description")) ? adj.getString("comments") : adj.getString("description")); createInvoiceItemAdjContext.put("description", description); // invoice items for sales tax are not taxable themselves // TODO: This is not an ideal solution. Instead, we need to use OrderAdjustment.includeInTax when it is implemented if (!(adj.getString("orderAdjustmentTypeId").equals("SALES_TAX"))) { createInvoiceItemAdjContext.put("taxableFlag", product.get("taxable")); } // If the OrderAdjustment is associated to a ProductPromo, // and the field ProductPromo.overrideOrgPartyId is set, // copy the value to InvoiceItem.overrideOrgPartyId: this // represent an organization override for the payToPartyId if (UtilValidate.isNotEmpty(adj.getString("productPromoId"))) { try { GenericValue productPromo = adj.getRelatedOne("ProductPromo", false); if (UtilValidate.isNotEmpty(productPromo.getString("overrideOrgPartyId"))) { createInvoiceItemAdjContext.put("overrideOrgPartyId", productPromo.getString("overrideOrgPartyId")); } } catch (GenericEntityException e) { Debug.logError(e, "Error looking up ProductPromo with id [" + adj.getString("productPromoId") + "]", module); } } Map<String, Object> createInvoiceItemAdjResult = dispatcher.runSync("createInvoiceItem", createInvoiceItemAdjContext); if (ServiceUtil.isError(createInvoiceItemAdjResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceItemFromOrder", locale), null, null, createInvoiceItemAdjResult); } // Create the OrderAdjustmentBilling record Map<String, Object> createOrderAdjustmentBillingContext = new HashMap<String, Object>(); createOrderAdjustmentBillingContext.put("orderAdjustmentId", adj.getString("orderAdjustmentId")); createOrderAdjustmentBillingContext.put("invoiceId", invoiceId); createOrderAdjustmentBillingContext.put("invoiceItemSeqId", invoiceItemSeqId); createOrderAdjustmentBillingContext.put("amount", amount); createOrderAdjustmentBillingContext.put("userLogin", userLogin); Map<String, Object> 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 = amount; // adjustments only apply to totals when they are not tax or shipping adjustments if (!"SALES_TAX".equals(adj.getString("orderAdjustmentTypeId")) && !"SHIPPING_ADJUSTMENT".equals(adj.getString("orderAdjustmentTypeId"))) { // increment the invoice subtotal invoiceSubTotal = invoiceSubTotal.add(thisAdjAmount).setScale(100, ROUNDING); // add to the ship amount only if it applies to this item if (shippingApplies) { invoiceShipProRateAmount = invoiceShipProRateAmount.add(thisAdjAmount) .setScale(invoiceTypeDecimals, ROUNDING); } } // increment the counter invoiceItemSeqNum++; invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, INVOICE_ITEM_SEQUENCE_ID_DIGITS); } } } // create header adjustments as line items -- always to tax/shipping last Map<GenericValue, BigDecimal> shipAdjustments = new HashMap<GenericValue, BigDecimal>(); Map<GenericValue, BigDecimal> taxAdjustments = new HashMap<GenericValue, BigDecimal>(); List<GenericValue> headerAdjustments = orh.getOrderHeaderAdjustments(); for (GenericValue adj : headerAdjustments) { // Check against OrderAdjustmentBilling to see how much of this adjustment has already been invoiced BigDecimal adjAlreadyInvoicedAmount = null; try { Map<String, Object> checkResult = dispatcher.runSync("calculateInvoicedAdjustmentTotal", UtilMisc.toMap("orderAdjustment", adj)); adjAlreadyInvoicedAmount = ((BigDecimal) checkResult.get("invoicedTotal")) .setScale(invoiceTypeDecimals, ROUNDING); } catch (GenericServiceException e) { Debug.logError(e, "Accounting trouble calling calculateInvoicedAdjustmentTotal service", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingTroubleCallingCalculateInvoicedAdjustmentTotalService", locale)); } // if (null == adj.get("amount")) { TODO check usage with webPos. Was: fix a bug coming from POS in case of use of a discount (on item(s) or sale, sale here) and a cash amount higher than total (hence issuing change) // continue; // } // 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(invoiceTypeDecimals, ROUNDING).abs()) >= 0) { continue; } if ("SHIPPING_CHARGES".equals(adj.getString("orderAdjustmentTypeId"))) { shipAdjustments.put(adj, adjAlreadyInvoicedAmount); } else if ("SALES_TAX".equals(adj.getString("orderAdjustmentTypeId"))) { taxAdjustments.put(adj, adjAlreadyInvoicedAmount); } else { // these will effect the shipping pro-rate (unless commented) // other adjustment type BigDecimal divisor = orderSubTotal; BigDecimal multiplier = invoiceSubTotal; if (BigDecimal.ZERO.compareTo(multiplier) == 0 && BigDecimal.ZERO.compareTo(divisor) == 0) { // if multiplier and divisor are equal to zero then use the quantities instead of the amounts // this is useful when the order has free items and misc charges divisor = orderQuantity; multiplier = invoiceQuantity; } calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId, divisor, multiplier, adj.getBigDecimal("amount").setScale(invoiceTypeDecimals, ROUNDING), invoiceTypeDecimals, ROUNDING, userLogin, dispatcher, locale); // invoiceShipProRateAmount += adjAmount; // do adjustments compound or are they based off subtotal? Here we will (unless commented) // invoiceSubTotal += adjAmount; // increment the counter invoiceItemSeqNum++; invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, INVOICE_ITEM_SEQUENCE_ID_DIGITS); } } // 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 for (GenericValue adj : shipAdjustments.keySet()) { BigDecimal adjAlreadyInvoicedAmount = shipAdjustments.get(adj); if ("N".equalsIgnoreCase(prorateShipping)) { // Set the divisor and multiplier to 1 to avoid prorating BigDecimal divisor = BigDecimal.ONE; BigDecimal multiplier = BigDecimal.ONE; // 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(invoiceTypeDecimals, ROUNDING) .subtract(adjAlreadyInvoicedAmount); calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId, divisor, multiplier, baseAmount, invoiceTypeDecimals, ROUNDING, userLogin, dispatcher, locale); } else { // Pro-rate the shipping amount based on shippable information BigDecimal divisor = shippableAmount; BigDecimal multiplier = invoiceShipProRateAmount; if (BigDecimal.ZERO.compareTo(multiplier) == 0 && BigDecimal.ZERO.compareTo(divisor) == 0) { // if multiplier and divisor are equal to zero then use the quantities instead of the amounts // this is useful when the order has free items and shipping charges divisor = shippableQuantity; multiplier = invoiceShippableQuantity; } // 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(invoiceTypeDecimals, ROUNDING); calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId, divisor, multiplier, baseAmount, invoiceTypeDecimals, ROUNDING, userLogin, dispatcher, locale); } // Increment the counter invoiceItemSeqNum++; invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, INVOICE_ITEM_SEQUENCE_ID_DIGITS); } // last do the tax adjustments String prorateTaxes = productStore != null ? productStore.getString("prorateTaxes") : "Y"; if (prorateTaxes == null) { prorateTaxes = "Y"; } for (Map.Entry<GenericValue, BigDecimal> entry : taxAdjustments.entrySet()) { GenericValue adj = entry.getKey(); BigDecimal adjAlreadyInvoicedAmount = entry.getValue(); BigDecimal adjAmount = null; if ("N".equalsIgnoreCase(prorateTaxes)) { // Set the divisor and multiplier to 1 to avoid prorating BigDecimal divisor = BigDecimal.ONE; BigDecimal multiplier = BigDecimal.ONE; // 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(TAX_DECIMALS, TAX_ROUNDING) .subtract(adjAlreadyInvoicedAmount); adjAmount = calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId, divisor, multiplier, baseAmount, TAX_DECIMALS, TAX_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 BigDecimal baseAmount = adj.getBigDecimal("amount"); adjAmount = calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId, divisor, multiplier, baseAmount, TAX_DECIMALS, TAX_ROUNDING, userLogin, dispatcher, locale); } invoiceSubTotal = invoiceSubTotal.add(adjAmount).setScale(invoiceTypeDecimals, ROUNDING); // Increment the counter invoiceItemSeqNum++; invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, INVOICE_ITEM_SEQUENCE_ID_DIGITS); } // check for previous order payments List<GenericValue> orderPaymentPrefs = EntityQuery.use(delegator).from("OrderPaymentPreference").where( EntityCondition.makeCondition("orderId", EntityOperator.EQUALS, orderId), EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "PAYMENT_CANCELLED")) .queryList(); List<GenericValue> currentPayments = new LinkedList<GenericValue>(); for (GenericValue paymentPref : orderPaymentPrefs) { List<GenericValue> payments = paymentPref.getRelated("Payment", null, null, false); currentPayments.addAll(payments); } // apply these payments to the invoice if they have any remaining amount to apply for (GenericValue payment : currentPayments) { if ("PMNT_VOID".equals(payment.getString("statusId")) || "PMNT_CANCELLED".equals(payment.getString("statusId"))) { continue; } BigDecimal notApplied = PaymentWorker.getPaymentNotApplied(payment); if (notApplied.signum() > 0) { Map<String, Object> appl = new HashMap<String, Object>(); appl.put("paymentId", payment.get("paymentId")); appl.put("invoiceId", invoiceId); appl.put("billingAccountId", billingAccountId); appl.put("amountApplied", notApplied); appl.put("userLogin", userLogin); Map<String, Object> createPayApplResult = dispatcher.runSync("createPaymentApplication", appl); if (ServiceUtil.isError(createPayApplResult)) { return ServiceUtil .returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceFromOrder", locale), null, null, createPayApplResult); } } } // Should all be in place now. Depending on the ProductStore.autoApproveInvoice setting, set status to INVOICE_READY (unless it's a purchase invoice, which we set to INVOICE_IN_PROCESS) String autoApproveInvoice = productStore != null ? productStore.getString("autoApproveInvoice") : "Y"; if (!"N".equals(autoApproveInvoice)) { String nextStatusId = "PURCHASE_INVOICE".equals(invoiceType) ? "INVOICE_IN_PROCESS" : "INVOICE_READY"; Map<String, Object> setInvoiceStatusResult = dispatcher.runSync("setInvoiceStatus", UtilMisc.<String, Object>toMap("invoiceId", invoiceId, "statusId", nextStatusId, "userLogin", userLogin)); if (ServiceUtil.isError(setInvoiceStatusResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceFromOrder", locale), null, null, setInvoiceStatusResult); } } Map<String, Object> resp = ServiceUtil.returnSuccess(); resp.put("invoiceId", invoiceId); resp.put("invoiceTypeId", invoiceType); return resp; } catch (GenericEntityException e) { Debug.logError(e, "Entity/data problem creating invoice from order items: " + e.toString(), module); return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingEntityDataProblemCreatingInvoiceFromOrderItems", UtilMisc.toMap("reason", e.toString()), locale)); } catch (GenericServiceException e) { Debug.logError(e, "Service/other problem creating invoice from order items: " + e.toString(), module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingServiceOtherProblemCreatingInvoiceFromOrderItems", UtilMisc.toMap("reason", e.toString()), locale)); } }
From source file:org.openbravo.erpCommon.ad_forms.AcctServer.java
public BigDecimal convertAmount(BigDecimal _amount, boolean isReceipt, String dateAcct, String table_ID, String record_ID, String currencyIDFrom, String currencyIDTo, DocLine line, AcctSchema as, Fact fact, String Fact_Acct_Group_ID, String seqNo, ConnectionProvider conn, boolean bookDifferences) throws ServletException { BigDecimal amtDiff = BigDecimal.ZERO; if (_amount == null || _amount.compareTo(BigDecimal.ZERO) == 0) { return _amount; }//from w w w . ja v a 2 s . c o m String conversionDate = dateAcct; String strDateFormat = OBPropertiesProvider.getInstance().getOpenbravoProperties() .getProperty("dateFormat.java"); final SimpleDateFormat dateFormat = new SimpleDateFormat(strDateFormat); ConversionRateDoc conversionRateDoc = getConversionRateDoc(table_ID, record_ID, currencyIDFrom, currencyIDTo); BigDecimal amtFrom = BigDecimal.ZERO; BigDecimal amtFromSourcecurrency = BigDecimal.ZERO; BigDecimal amtTo = BigDecimal.ZERO; if (table_ID.equals(TABLEID_Invoice)) { Invoice invoice = OBDal.getInstance().get(Invoice.class, record_ID); conversionDate = dateFormat.format(invoice.getAccountingDate()); } else if (table_ID.equals(TABLEID_Payment)) { FIN_Payment payment = OBDal.getInstance().get(FIN_Payment.class, record_ID); conversionDate = dateFormat.format(payment.getPaymentDate()); } else if (table_ID.equals(TABLEID_Transaction)) { FIN_FinaccTransaction transaction = OBDal.getInstance().get(FIN_FinaccTransaction.class, record_ID); conversionDate = dateFormat.format(transaction.getDateAcct()); } if (conversionRateDoc != null && record_ID != null) { amtFrom = applyRate(_amount, conversionRateDoc, true); } else { // I try to find a reversal rate for the doc, if exists i apply it reversal as well conversionRateDoc = getConversionRateDoc(table_ID, record_ID, currencyIDTo, currencyIDFrom); if (conversionRateDoc != null) { amtFrom = applyRate(_amount, conversionRateDoc, false); } else { String convertedAmt = getConvertedAmt(_amount.toString(), currencyIDFrom, currencyIDTo, conversionDate, "", AD_Client_ID, AD_Org_ID, conn); if (convertedAmt != null && !"".equals(convertedAmt)) { amtFrom = new BigDecimal(convertedAmt); } else { throw new OBException("@NotConvertible@"); } } } ConversionRateDoc conversionRateCurrentDoc = getConversionRateDoc(AD_Table_ID, Record_ID, currencyIDFrom, currencyIDTo); if (AD_Table_ID.equals(TABLEID_Invoice)) { Invoice invoice = OBDal.getInstance().get(Invoice.class, Record_ID); conversionDate = dateFormat.format(invoice.getAccountingDate()); } else if (AD_Table_ID.equals(TABLEID_Payment)) { FIN_Payment payment = OBDal.getInstance().get(FIN_Payment.class, Record_ID); conversionDate = dateFormat.format(payment.getPaymentDate()); } else if (AD_Table_ID.equals(TABLEID_Transaction) || AD_Table_ID.equals(TABLEID_Reconciliation)) { String transactionID = Record_ID; // When TableID= Reconciliation info is loaded from transaction if (AD_Table_ID.equals(AcctServer.TABLEID_Reconciliation) && line instanceof DocLine_FINReconciliation) { transactionID = ((DocLine_FINReconciliation) line).getFinFinAccTransactionId(); } FIN_FinaccTransaction transaction = OBDal.getInstance().get(FIN_FinaccTransaction.class, transactionID); conversionDate = dateFormat.format(transaction.getDateAcct()); conversionRateCurrentDoc = getConversionRateDoc(TABLEID_Transaction, transaction.getId(), currencyIDFrom, currencyIDTo); } else { conversionDate = dateAcct; } if (conversionRateCurrentDoc != null) { amtTo = applyRate(_amount, conversionRateCurrentDoc, true); amtFromSourcecurrency = applyRate(amtFrom, conversionRateCurrentDoc, false); } else { // I try to find a reversal rate for the doc, if exists i apply it reversal as well if (AD_Table_ID.equals(AcctServer.TABLEID_Reconciliation) && line instanceof DocLine_FINReconciliation) { String transactionID = ((DocLine_FINReconciliation) line).getFinFinAccTransactionId(); conversionRateCurrentDoc = getConversionRateDoc(TABLEID_Transaction, transactionID, currencyIDTo, currencyIDFrom); } else { conversionRateCurrentDoc = getConversionRateDoc(AD_Table_ID, Record_ID, currencyIDTo, currencyIDFrom); } if (conversionRateCurrentDoc != null) { amtTo = applyRate(_amount, conversionRateCurrentDoc, false); amtFromSourcecurrency = applyRate(amtFrom, conversionRateCurrentDoc, true); } else { String convertedAmt = getConvertedAmt(_amount.toString(), currencyIDFrom, currencyIDTo, conversionDate, "", AD_Client_ID, AD_Org_ID, conn); if (convertedAmt != null && !"".equals(convertedAmt)) { amtTo = new BigDecimal(convertedAmt); } else { throw new OBException("@NotConvertible@"); } if (amtTo.compareTo(BigDecimal.ZERO) != 0) amtFromSourcecurrency = amtFrom.multiply(_amount).divide(amtTo, conversionRatePrecision, BigDecimal.ROUND_HALF_EVEN); else amtFromSourcecurrency = amtFrom; } } amtDiff = (amtTo).subtract(amtFrom); // Add differences related to Different rates for accounting among currencies // _amount * ((TrxRate * // AccountingRateCurrencyFromCurrencyTo)-AccountingRateCurrencyDocCurrencyTo) amtDiff = amtDiff.add(calculateMultipleRatesDifferences(_amount, currencyIDFrom, currencyIDTo, line, conn)); Currency currencyTo = OBDal.getInstance().get(Currency.class, currencyIDTo); amtDiff = amtDiff.setScale(currencyTo.getStandardPrecision().intValue(), BigDecimal.ROUND_HALF_EVEN); if (bookDifferences) { if ((!isReceipt && amtDiff.compareTo(BigDecimal.ZERO) == 1) || (isReceipt && amtDiff.compareTo(BigDecimal.ZERO) == -1)) { fact.createLine(line, getAccount(AcctServer.ACCTTYPE_ConvertGainDefaultAmt, as, conn), currencyIDTo, "", amtDiff.abs().toString(), Fact_Acct_Group_ID, seqNo, DocumentType, conn); } else if (amtDiff.compareTo(BigDecimal.ZERO) != 0) { fact.createLine(line, getAccount(AcctServer.ACCTTYPE_ConvertChargeDefaultAmt, as, conn), currencyIDTo, amtDiff.abs().toString(), "", Fact_Acct_Group_ID, seqNo, DocumentType, conn); } else { return amtFromSourcecurrency; } } if (log4j.isDebugEnabled()) log4j.debug("Amt from: " + amtFrom + "[" + currencyIDFrom + "]" + " Amt to: " + amtTo + "[" + currencyIDTo + "] - amtFromSourcecurrency: " + amtFromSourcecurrency); // return value in original currency return amtFromSourcecurrency; }
From source file:org.ofbiz.order.order.OrderServices.java
public static BigDecimal calculatePurchaseOrderTermValue(DispatchContext ctx, Map<String, ? extends Object> context) { BigDecimal termAmount = BigDecimal.ZERO; BigDecimal basicAmount = (BigDecimal) context.get("basicAmount"); BigDecimal poValue = (BigDecimal) context.get("poValue"); BigDecimal exciseDuty = (BigDecimal) context.get("exciseDuty"); String termTypeId = (String) context.get("termTypeId"); String uomId = (String) context.get("uomId"); BigDecimal termValue = (BigDecimal) context.get("termValue"); if (UtilValidate.isEmpty(termTypeId)) { return termAmount; }/*from w ww . j a v a2 s . c o m*/ //this to handle non derived terms termAmount = termValue; //Discount Before ED if (termTypeId.equals("COGS_DISC")) { if (UtilValidate.isNotEmpty(uomId) && uomId.equals("PERCENT")) { termAmount = ((basicAmount.add(exciseDuty)).multiply(termValue)).divide(new BigDecimal("100"), taxRounding); termAmount = termAmount.negate(); } else { termAmount = termValue.negate(); } } //Discount After Tax if (termTypeId.equals("COGS_DISC_ATR")) { if (UtilValidate.isNotEmpty(uomId) && uomId.equals("PERCENT")) { Debug.log("poValue========" + poValue); termAmount = (poValue.multiply(termValue)).divide(new BigDecimal("100"), taxRounding); termAmount = termAmount.negate(); } else { termAmount = termValue.negate(); } } //Packing And Forwarding Charges Before Tax if (termTypeId.equals("COGS_PCK_FWD")) { if (UtilValidate.isNotEmpty(uomId) && uomId.equals("PERCENT")) { termAmount = ((basicAmount.add(exciseDuty)).multiply(termValue)).divide(new BigDecimal("100"), taxRounding); } else { termAmount = termValue; } } //Packing And Forwarding Charges After Tax if (termTypeId.equals("COGS_PCK_FWD_ATR")) { if (UtilValidate.isNotEmpty(uomId) && uomId.equals("PERCENT")) { Debug.log("poValue========" + poValue); termAmount = (poValue.multiply(termValue)).divide(new BigDecimal("100"), taxRounding); } else { termAmount = termValue; } } if (termTypeId.equals("COGS_INSURANCE")) { if (UtilValidate.isNotEmpty(uomId) && uomId.equals("PERCENT")) { termAmount = ((basicAmount.add(exciseDuty)).multiply(termValue)).divide(new BigDecimal("100"), taxRounding); } else { termAmount = termValue; } } return termAmount; }
From source file:com.turborep.turbotracker.banking.service.BankingServiceImpl.java
@Override public Integer createtransactionBanknewCheck(MoAccount moAccount, Motransaction M1, String DepositType, Integer yearID, Integer periodID, String userName, BigDecimal balance, boolean accountStatus, int motransiid, String oper, String gridData, boolean futureornot, BigDecimal currentbalance, BigDecimal oldamount, String NewMoTypeId, BigDecimal amt, String aMemo, String aRxMasterID) throws BankingException, CompanyException { Transaction aTransaction;/* w w w . j a v a2 s. c om*/ Session aSession = null; aSession = itsSessionFactory.openSession(); aTransaction = aSession.beginTransaction(); try { aTransaction.begin(); if (oper.equals("new")) { updateDepositAndWithDraw(moAccount, aSession); M1.setBalance(balance); motransiid = addTransactionDetails(M1, aSession, "new"); M1.setMoTransactionId(motransiid); if (accountStatus) gltransactionService.bankingDeposits(M1, DepositType, yearID, periodID, userName, aSession); } else if (oper.equals("add")) { Momultipleaccount momulaccount = null; BigDecimal TotalAmt = new BigDecimal(0); updateDepositAndWithDraw(moAccount, aSession); M1.setBalance(balance); motransiid = addTransactionDetails(M1, aSession, "new"); M1.setMoTransactionId(motransiid); if (accountStatus) { gltransactionService.bankingDeposits(M1, DepositType, yearID, periodID, userName, aSession); } else { JsonParser parser = new JsonParser(); if (null != gridData && gridData.length() > 6) { JsonElement ele = parser.parse(gridData); JsonArray array = ele.getAsJsonArray(); System.out.println("array length==>" + array.size()); for (JsonElement ele1 : array) { momulaccount = new Momultipleaccount(); JsonObject obj = ele1.getAsJsonObject(); momulaccount.setCoAccountId(obj.get("coAccountId").getAsInt()); M1.setCoAccountId(obj.get("coAccountId").getAsInt()); momulaccount.setAmount(obj.get("amount").getAsBigDecimal()); M1.setAmount(obj.get("amount").getAsBigDecimal()); momulaccount.setMoTransactionId(motransiid); momulaccount.setMoMultipleAccountsId(obj.get("moMultipleAccountsId").getAsInt()); System.out.println("checkupdates" + momulaccount.getCoAccountId() + "==" + momulaccount.getAmount() + "==" + obj.get("moMultipleAccountsId").getAsInt()); if (obj.get("moMultipleAccountsId").getAsInt() == 0) { saveGlmultipleAccount1(momulaccount, aSession); } else { updateGlmultipleAccount1(momulaccount, aSession); } DepositType = "Multiple with subaccounts"; gltransactionService.bankingDeposits(M1, DepositType, yearID, periodID, userName, aSession); TotalAmt = TotalAmt.add(obj.get("amount").getAsBigDecimal()); } DepositType = "Multiple with mainaccounts"; M1.setAmount(TotalAmt); gltransactionService.bankingDeposits(M1, DepositType, yearID, periodID, userName, aSession); } } } else if (oper.equals("edit")) { Momultipleaccount momulaccount = null; BigDecimal TotalAmt = new BigDecimal(0); updateTransactionDetails1(M1, aSession); Coledgersource aColedgersource = gltransactionService.getColedgersourceDetail("BT"); GlRollback glRollback = new GlRollback(); glRollback.setVeBillID(M1.getMoTransactionId()); glRollback.setCoLedgerSourceID(aColedgersource.getCoLedgerSourceId()); glRollback.setPeriodID(periodID); glRollback.setYearID(yearID); glRollback.setTransactionDate(M1.getTransactionDate()); gltransactionService.rollBackGlTransaction1(glRollback, aSession); String aDescription = M1.getDescription(); String aReference = M1.getReference(); if (M1.getMoTransactionTypeId() == 0) { /*if(futureornot){ balance=currentbalance.subtract(oldamount); }else{ balance=currentbalance; }*/ balance = currentbalance.subtract(oldamount); oldamount = oldamount.multiply(new BigDecimal(-1)); short change = 1; M1.setMoTransactionTypeId(change); moAccount.setSubtractions(oldamount); // 220 } else { /*if(futureornot){ balance=currentbalance.add(oldamount); }else{ balance=currentbalance; }*/ balance = currentbalance.add(oldamount); short change = 0; M1.setMoTransactionTypeId(change); moAccount.setAdditions(oldamount); } moAccount.setMoTransactionTypeId(M1.getMoTransactionTypeId()); updateDepositAndWithDraw(moAccount, aSession); M1.setAmount(oldamount); M1.setBalance(balance); addTransactionDetails(M1, aSession, "rollback"); BigDecimal newbalance = new BigDecimal("0.00"); short editmotypeid = Short.parseShort(NewMoTypeId); M1.setMoTransactionTypeId(editmotypeid); M1.setAmount(amt); M1.setStatus(false); if (M1.getMoTransactionTypeId() == 0) { if (M1.getAmount().doubleValue() < 0) { M1.setAmount(M1.getAmount().multiply(new BigDecimal(-1))); } /*if(futureornot){ newbalance=balance.add(M1.getAmount()); }else{ newbalance=currentbalance; }*/ newbalance = balance.add(M1.getAmount()); moAccount.setAdditions(M1.getAmount()); } else { if (M1.getAmount().doubleValue() > 0) { M1.setAmount(M1.getAmount().multiply(new BigDecimal(-1))); } /*if(futureornot){ newbalance=balance.add(M1.getAmount()); }else{ newbalance=currentbalance; }*/ newbalance = balance.add(M1.getAmount()); moAccount.setSubtractions(M1.getAmount()); } M1.setBalance(newbalance); moAccount.setMoTransactionTypeId(M1.getMoTransactionTypeId()); updateDepositAndWithDraw(moAccount, aSession); if (editmotypeid == 2) { M1.setMemo(aMemo); M1.setRxMasterId(Integer.parseInt(aRxMasterID)); } M1.setDescription(aDescription); M1.setReference(aReference); motransiid = addTransactionDetails(M1, aSession, "new"); M1.setMoTransactionId(motransiid); if (accountStatus == true) { gltransactionService.bankingDeposits(M1, DepositType, yearID, periodID, userName, aSession); } else { JsonParser parser = new JsonParser(); if (null != gridData && gridData.length() > 6) { if ((oper.equals("edit") || oper.equals("delete"))) { glRollback.setVeBillID(M1.getMoTransactionId()); glRollback.setCoLedgerSourceID(aColedgersource.getCoLedgerSourceId()); glRollback.setPeriodID(periodID); glRollback.setYearID(yearID); glRollback.setTransactionDate(M1.getTransactionDate()); gltransactionService.rollBackGlTransaction1(glRollback, aSession); } JsonElement ele = parser.parse(gridData); JsonArray array = ele.getAsJsonArray(); System.out.println("array length==>" + array.size()); for (JsonElement ele1 : array) { momulaccount = new Momultipleaccount(); JsonObject obj = ele1.getAsJsonObject(); momulaccount.setCoAccountId(obj.get("coAccountId").getAsInt()); M1.setCoAccountId(obj.get("coAccountId").getAsInt()); momulaccount.setAmount(obj.get("amount").getAsBigDecimal()); M1.setAmount(obj.get("amount").getAsBigDecimal()); momulaccount.setMoTransactionId(motransiid); momulaccount.setMoMultipleAccountsId(obj.get("moMultipleAccountsId").getAsInt()); System.out.println("checkupdates" + momulaccount.getCoAccountId() + "==" + momulaccount.getAmount() + "==" + obj.get("moMultipleAccountsId").getAsInt()); if (obj.get("moMultipleAccountsId").getAsInt() == 0) { saveGlmultipleAccount1(momulaccount, aSession); } else { updateGlmultipleAccount1(momulaccount, aSession); } DepositType = "Multiple with subaccounts"; gltransactionService.bankingDeposits(M1, DepositType, yearID, periodID, userName, aSession); TotalAmt = TotalAmt.add(obj.get("amount").getAsBigDecimal()); } DepositType = "Multiple with mainaccounts"; M1.setAmount(TotalAmt); gltransactionService.bankingDeposits(M1, DepositType, yearID, periodID, userName, aSession); } } } else if (oper.equals("delete")) { updateTransactionDetails1(M1, aSession); Coledgersource aColedgersource = gltransactionService.getColedgersourceDetail("BT"); GlRollback glRollback = new GlRollback(); glRollback.setVeBillID(M1.getMoTransactionId()); glRollback.setCoLedgerSourceID(aColedgersource.getCoLedgerSourceId()); glRollback.setPeriodID(periodID); glRollback.setYearID(yearID); glRollback.setTransactionDate(new Date()); gltransactionService.rollBackGlTransaction1(glRollback, aSession); balance = new BigDecimal("0.00"); if (M1.getMoTransactionTypeId() == 0) { if (M1.getAmount().doubleValue() < 0) { M1.setAmount(M1.getAmount().multiply(new BigDecimal(-1))); } moAccount.setSubtractions(M1.getAmount()); /*if(futureornot){ balance=currentbalance.add(M1.getAmount()); }else{ balance=currentbalance; }*/ balance = currentbalance.add(M1.getAmount()); } else { if (M1.getAmount().doubleValue() > 0) { M1.setAmount(M1.getAmount().multiply(new BigDecimal(-1))); } moAccount.setAdditions(M1.getAmount()); /*if(futureornot){ balance=currentbalance.add(M1.getAmount()); }else{ balance=currentbalance; }*/ balance = currentbalance.add(M1.getAmount()); } moAccount.setOper(oper); updateDepositAndWithDraw(moAccount, aSession); M1.setStatus(true); M1.setBalance(balance); addTransactionDetails(M1, aSession, "rollback"); } else if (oper.equals("void")) { boolean statusChk = true; statusChk = voidTransactionDetails1(M1, aSession); GlRollback glRollback = new GlRollback(); if (statusChk) { Coledgersource aColedgersource = gltransactionService.getColedgersourceDetail("WC"); glRollback.setVeBillID(Integer.parseInt(M1.getMoAccountId() + "" + M1.getReference())); glRollback.setCoLedgerSourceID(aColedgersource.getCoLedgerSourceId()); glRollback.setPeriodID(periodID); glRollback.setYearID(yearID); glRollback.setTransactionDate(new Date()); gltransactionService.rollBackGlTransaction1(glRollback, aSession); } else { Coledgersource aColedgersource = gltransactionService.getColedgersourceDetail("BT"); glRollback.setVeBillID(M1.getMoTransactionId()); glRollback.setCoLedgerSourceID(aColedgersource.getCoLedgerSourceId()); glRollback.setPeriodID(periodID); glRollback.setYearID(yearID); glRollback.setTransactionDate(new Date()); gltransactionService.rollBackGlTransaction1(glRollback, aSession); } balance = new BigDecimal("0.00"); if (M1.getMoTransactionTypeId() == 0) { if (M1.getAmount().doubleValue() < 0) { M1.setAmount(M1.getAmount().multiply(new BigDecimal(-1))); } moAccount.setSubtractions(M1.getAmount()); /*if(futureornot){ balance=currentbalance.add(M1.getAmount()); }else{ balance=currentbalance; }*/ balance = currentbalance.add(M1.getAmount()); } else { if (M1.getAmount().doubleValue() < 0) { M1.setAmount(M1.getAmount().multiply(new BigDecimal(-1))); } moAccount.setAdditions(M1.getAmount()); /*if(futureornot){ balance=currentbalance.add(M1.getAmount()); }else{ balance=currentbalance; }*/ balance = currentbalance.add(M1.getAmount()); } moAccount.setOper(oper); updateDepositAndWithDraw(moAccount, aSession); M1.setStatus(false); M1.setBalance(balance); M1.setDescription("[VOID]" + M1.getDescription()); M1.setUniquechkRef(M1.getReference()); addTransactionDetails(M1, aSession, "rollbackfromvoid"); } aTransaction.commit(); } catch (Exception e) { itsLogger.error(e.getMessage(), e); aTransaction.rollback(); CompanyException aCompanyException = new CompanyException(e.getCause().getMessage(), e); throw aCompanyException; } finally { aSession.flush(); aSession.close(); } return motransiid; }
From source file:org.openbravo.erpCommon.ad_forms.AcctServer.java
private BigDecimal calculateMultipleRatesDifferences(BigDecimal _amount, String currencyIDFrom, String currencyIDTo, DocLine line, ConnectionProvider conn) { // _amount * ((TrxRate * // AccountingRateCurrencyFromCurrencyTo)-AccountingRateCurrencyDocCurrencyTo) String conversionDate = DateAcct; String strDateFormat = OBPropertiesProvider.getInstance().getOpenbravoProperties() .getProperty("dateFormat.java"); final SimpleDateFormat dateFormat = new SimpleDateFormat(strDateFormat); // Calculate accountingRateCurrencyFromCurrencyTo BigDecimal accountingRateCurrencyFromCurrencyTo = BigDecimal.ONE; if (!currencyIDFrom.equals(currencyIDTo)) { ConversionRateDoc conversionRateCurrentDoc = getConversionRateDoc(AD_Table_ID, Record_ID, currencyIDFrom, currencyIDTo); if (AD_Table_ID.equals(AcctServer.TABLEID_Reconciliation) && line instanceof DocLine_FINReconciliation) { String transactionID = ((DocLine_FINReconciliation) line).getFinFinAccTransactionId(); FIN_FinaccTransaction transaction = OBDal.getInstance().get(FIN_FinaccTransaction.class, transactionID);/*from w w w . j a va2 s . c o m*/ conversionDate = dateFormat.format(transaction.getDateAcct()); conversionRateCurrentDoc = getConversionRateDoc(TABLEID_Transaction, transaction.getId(), currencyIDFrom, currencyIDTo); } if (conversionRateCurrentDoc != null) { accountingRateCurrencyFromCurrencyTo = conversionRateCurrentDoc.getRate(); } else { // I try to find a reversal rate for the doc, if exists i apply it reversal as well if (AD_Table_ID.equals(AcctServer.TABLEID_Reconciliation) && line instanceof DocLine_FINReconciliation) { String transactionID = ((DocLine_FINReconciliation) line).getFinFinAccTransactionId(); FIN_FinaccTransaction transaction = OBDal.getInstance().get(FIN_FinaccTransaction.class, transactionID); conversionRateCurrentDoc = getConversionRateDoc(TABLEID_Transaction, transaction.getId(), currencyIDTo, currencyIDFrom); } else { conversionRateCurrentDoc = getConversionRateDoc(AD_Table_ID, Record_ID, currencyIDTo, currencyIDFrom); } if (conversionRateCurrentDoc != null) { accountingRateCurrencyFromCurrencyTo = BigDecimal.ONE.divide(conversionRateCurrentDoc.getRate(), MathContext.DECIMAL64); } else { accountingRateCurrencyFromCurrencyTo = getConvertionRate(currencyIDFrom, currencyIDTo, conversionDate, "", AD_Client_ID, AD_Org_ID, conn); } } } // Calculate accountingRateCurrencyFromCurrencyTo BigDecimal accountingRateCurrencyDocCurrencyTo = BigDecimal.ONE; if (!C_Currency_ID.equals(currencyIDTo)) { ConversionRateDoc conversionRateCurrentDoc = getConversionRateDoc(AD_Table_ID, Record_ID, C_Currency_ID, currencyIDTo); if (AD_Table_ID.equals(AcctServer.TABLEID_Reconciliation) && line instanceof DocLine_FINReconciliation) { String transactionID = ((DocLine_FINReconciliation) line).getFinFinAccTransactionId(); FIN_FinaccTransaction transaction = OBDal.getInstance().get(FIN_FinaccTransaction.class, transactionID); conversionDate = dateFormat.format(transaction.getTransactionDate()); conversionRateCurrentDoc = getConversionRateDoc(TABLEID_Transaction, transaction.getId(), C_Currency_ID, currencyIDTo); } if (conversionRateCurrentDoc != null) { accountingRateCurrencyDocCurrencyTo = conversionRateCurrentDoc.getRate(); } else { // I try to find a reversal rate for the doc, if exists i apply it reversal as well if (AD_Table_ID.equals(AcctServer.TABLEID_Reconciliation) && line instanceof DocLine_FINReconciliation) { String transactionID = ((DocLine_FINReconciliation) line).getFinFinAccTransactionId(); FIN_FinaccTransaction transaction = OBDal.getInstance().get(FIN_FinaccTransaction.class, transactionID); conversionRateCurrentDoc = getConversionRateDoc(TABLEID_Transaction, transaction.getId(), currencyIDTo, C_Currency_ID); } else { conversionRateCurrentDoc = getConversionRateDoc(AD_Table_ID, Record_ID, currencyIDTo, C_Currency_ID); } if (conversionRateCurrentDoc != null) { accountingRateCurrencyDocCurrencyTo = BigDecimal.ONE.divide(conversionRateCurrentDoc.getRate(), MathContext.DECIMAL64); } else { accountingRateCurrencyDocCurrencyTo = getConvertionRate(C_Currency_ID, currencyIDTo, conversionDate, "", AD_Client_ID, AD_Org_ID, conn); } } } // Calculate transaction rate BigDecimal trxRate = BigDecimal.ONE; if (!C_Currency_ID.equals(currencyIDFrom)) { if (AD_Table_ID.equals(TABLEID_Payment)) { FIN_Payment payment = OBDal.getInstance().get(FIN_Payment.class, Record_ID); trxRate = payment.getFinancialTransactionConvertRate(); } else if (AD_Table_ID.equals(TABLEID_Transaction) || AD_Table_ID.equals(TABLEID_Reconciliation)) { String transactionID = Record_ID; // When TableID = Reconciliation info is loaded from transaction if (AD_Table_ID.equals(AcctServer.TABLEID_Reconciliation) && line instanceof DocLine_FINReconciliation) { transactionID = ((DocLine_FINReconciliation) line).getFinFinAccTransactionId(); } FIN_FinaccTransaction transaction = OBDal.getInstance().get(FIN_FinaccTransaction.class, transactionID); trxRate = transaction.getForeignConversionRate(); } } Currency currencyFrom = OBDal.getInstance().get(Currency.class, currencyIDTo); return _amount .multiply(trxRate.multiply(accountingRateCurrencyDocCurrencyTo) .subtract(accountingRateCurrencyFromCurrencyTo)) .setScale(currencyFrom.getStandardPrecision().intValue(), BigDecimal.ROUND_HALF_EVEN); }
From source file:com.lp.server.fertigung.ejbfac.FertigungFacBean.java
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) public BigDecimal getAusgegebeneMengePreis(Integer lossollmaterialIId, java.sql.Timestamp tStichtag, TheClientDto theClientDto) throws EJBExceptionLP { try {/*from www .ja va2 s . co m*/ BigDecimal bdMenge = new BigDecimal(0); BigDecimal bdWert = new BigDecimal(0); LosistmaterialDto[] losist = losistmaterialFindByLossollmaterialIId(lossollmaterialIId); for (int i = 0; i < losist.length; i++) { BigDecimal bdAusgegeben = getLagerFac().getMengeEinerBelegposition(LocaleFac.BELEGART_LOS, losist[i].getIId(), tStichtag); if (Helper.short2boolean(losist[i].getBAbgang())) { BigDecimal bdPreis = getLagerFac().getGemittelterGestehungspreisEinerAbgangsposition( LocaleFac.BELEGART_LOS, losist[i].getIId()); bdMenge = bdMenge.add(bdAusgegeben); bdWert = bdWert.add(bdPreis.multiply(bdAusgegeben)); } else { BigDecimal bdPreis = getLagerFac().getGemittelterEinstandspreisEinerZugangsposition( LocaleFac.BELEGART_LOS, losist[i].getIId()); bdMenge = bdMenge.subtract(bdAusgegeben); bdWert = bdWert.subtract(bdPreis.multiply(bdAusgegeben)); } } if (bdMenge.doubleValue() == 0) { return bdMenge; } else { return bdWert.divide(bdMenge, BigDecimal.ROUND_HALF_EVEN); } } catch (RemoteException ex) { throwEJBExceptionLPRespectOld(ex); return null; } }
From source file:com.lp.server.fertigung.ejbfac.FertigungFacBean.java
public void aendereLosgroesse(Integer losIId, Integer neueLosgroesse, boolean bUeberzaehligesMaterialZurueckgeben, TheClientDto theClientDto) { LosDto losDto = losFindByPrimaryKey(losIId); if (losDto.getStatusCNr().equals(FertigungFac.STATUS_AUSGEGEBEN) || losDto.getStatusCNr().equals(FertigungFac.STATUS_IN_PRODUKTION) || losDto.getStatusCNr().equals(FertigungFac.STATUS_GESTOPPT) || losDto.getStatusCNr().equals(FertigungFac.STATUS_TEILERLEDIGT)) { if (!losDto.getNLosgroesse().equals(new BigDecimal(neueLosgroesse))) { BigDecimal bdErledigte = getErledigteMenge(losDto.getIId(), theClientDto); if (bdErledigte.doubleValue() > neueLosgroesse.doubleValue()) { throw new EJBExceptionLP( EJBExceptionLP.FEHLER_FERTIGUNG_AENDERUNG_LOGROESSE_ZUVIELEABLIEFERUNGEN, new Exception("bdErledigte.doubleValue()>neueLosgroesse.doubleValue()")); }/* w w w. ja va2s. c om*/ Los los = em.find(Los.class, losDto.getIId()); los.setNLosgroesse(new BigDecimal(neueLosgroesse)); em.merge(los); em.flush(); // Material LossollmaterialDto[] dtos = lossollmaterialFindByLosIId(losIId); for (int i = 0; i < dtos.length; i++) { LossollmaterialDto dto = dtos[i]; // Sollmengen aendern BigDecimal sollsatzgroesse = dto.getNMenge().divide(losDto.getNLosgroesse(), 10, BigDecimal.ROUND_HALF_EVEN); dto.setNMenge( Helper.rundeKaufmaennisch(sollsatzgroesse.multiply(new BigDecimal(neueLosgroesse)), 3)); updateLossollmaterial(dto, theClientDto); // Wenn kleiner je nach parameter // bUeberzaehligesMaterialZurueckgeben material // zurueckbuchen if (neueLosgroesse.doubleValue() < losDto.getNLosgroesse().doubleValue() && bUeberzaehligesMaterialZurueckgeben == true) { BigDecimal bdAusgegeben = getAusgegebeneMenge(dto.getIId(), null, theClientDto); BigDecimal diff = bdAusgegeben.subtract(dto.getNMenge()); if (diff.doubleValue() > 0) { LosistmaterialDto[] dtosLosist = losistmaterialFindByLossollmaterialIId(dto.getIId()); for (int j = 0; j < dtosLosist.length; j++) { if (diff.doubleValue() > 0) { BigDecimal istmenge = dtosLosist[j].getNMenge(); BigDecimal bdMengeNeu = null; if (diff.doubleValue() > istmenge.doubleValue()) { bdMengeNeu = new BigDecimal(0); diff = diff.subtract(istmenge); } else { bdMengeNeu = istmenge.subtract(diff); diff = new BigDecimal(0); } updateLosistmaterialMenge(dtosLosist[j].getIId(), bdMengeNeu, theClientDto); } } } } // Fehlmengen aktualisieren try { getFehlmengeFac().aktualisiereFehlmenge(LocaleFac.BELEGART_LOS, dto.getIId(), false, theClientDto); } catch (RemoteException e) { throwEJBExceptionLPRespectOld(e); } } // Arbeitsplan LossollarbeitsplanDto[] arbeitsplan = lossollarbeitsplanFindByLosIId(losIId); for (int i = 0; i < arbeitsplan.length; i++) { LossollarbeitsplanDto dto = arbeitsplan[i]; // Gesamtzeit wird austomatisch aktualisiert updateLossollarbeitsplan(dto, theClientDto); } } } else { if (losDto.getStatusCNr().equals(FertigungFac.STATUS_STORNIERT)) { throw new EJBExceptionLP(EJBExceptionLP.FEHLER_FERTIGUNG_DAS_LOS_IST_STORNIERT, new Exception("los " + losDto.getCNr() + " ist storniert")); } else if (losDto.getStatusCNr().equals(FertigungFac.STATUS_ERLEDIGT)) { throw new EJBExceptionLP(EJBExceptionLP.FEHLER_FERTIGUNG_DAS_LOS_IST_BEREITS_ERLEDIGT, new Exception("los " + losDto.getCNr() + " ist bereits erledigt")); } else if (losDto.getStatusCNr().equals(FertigungFac.STATUS_ANGELEGT)) { throw new EJBExceptionLP(EJBExceptionLP.FEHLER_FERTIGUNG_DAS_LOS_IST_NOCH_NICHT_AUSGEGEBEN, new Exception("los " + losDto.getCNr() + " ist noch nicht ausgegeben")); } } }
From source file:com.lp.server.fertigung.ejbfac.FertigungFacBean.java
private void aktualisiereAZAllerLosablieferungen(Integer losIId, TheClientDto theClientDto) { LosDto losDto = losFindByPrimaryKey(losIId); try {//from www. j ava 2 s . c o m // Sollzeiten LossollarbeitsplanDto[] soll = lossollarbeitsplanFindByLosIId(losDto.getIId()); int SOLL = 0; int IST = 1; int WERT = 2; // Sollzeiten nach Artikel verdichten HashMap<Integer, Object[]> listSollVerdichtet = new HashMap<Integer, Object[]>(); for (int i = 0; i < soll.length; i++) { if (listSollVerdichtet.containsKey(soll[i].getArtikelIIdTaetigkeit())) { Object[] oTemp = listSollVerdichtet.get(soll[i].getArtikelIIdTaetigkeit()); BigDecimal sollZeit = soll[i].getNGesamtzeit(); if (soll[i].getMaschineIId() != null) { sollZeit = sollZeit.multiply(new BigDecimal(2)); } oTemp[SOLL] = ((BigDecimal) oTemp[SOLL]).add(sollZeit); oTemp[IST] = new BigDecimal(0.00); oTemp[WERT] = new BigDecimal(0.00); listSollVerdichtet.put(soll[i].getArtikelIIdTaetigkeit(), oTemp); } else { Object[] oZeile = new Object[3]; BigDecimal sollZeit = soll[i].getNGesamtzeit(); if (soll[i].getMaschineIId() != null) { sollZeit = sollZeit.multiply(new BigDecimal(2)); } oZeile[SOLL] = sollZeit; oZeile[IST] = new BigDecimal(0.00); oZeile[WERT] = new BigDecimal(0.00); listSollVerdichtet.put(soll[i].getArtikelIIdTaetigkeit(), oZeile); } } // Maschinenzeiten AuftragzeitenDto[] zeitenMaschine = getZeiterfassungFac().getAllMaschinenzeitenEinesBeleges(losIId, null, null, null, theClientDto); // "normale" Zeiten AuftragzeitenDto[] zeitenMann = getZeiterfassungFac().getAllZeitenEinesBeleges(LocaleFac.BELEGART_LOS, losIId, null, null, null, null, false, false, theClientDto); LosablieferungDto[] losablieferungDtos = losablieferungFindByLosIIdOhneNeuberechnungUndOhneSnrChnr( losIId, theClientDto); boolean bErledigtOderUeberliefert = false; BigDecimal bdGesamtAbgeliefert = new BigDecimal(0.00); for (int i = 0; i < losablieferungDtos.length; i++) { LosablieferungDto losablieferungDto = losablieferungDtos[i]; bdGesamtAbgeliefert = bdGesamtAbgeliefert.add(losablieferungDto.getNMenge()); } if (losDto.getStatusCNr().equals(LocaleFac.STATUS_ERLEDIGT) || bdGesamtAbgeliefert.doubleValue() >= losDto.getNLosgroesse().doubleValue()) { bErledigtOderUeberliefert = true; } BigDecimal bdKostenGesamt = new BigDecimal(0.00); BigDecimal bdVerbrauchteKostenGesamt = new BigDecimal(0.00); HashMap<Integer, BigDecimal> hmUeberigeZeitderVorhergehendenAblieferung = new HashMap(); HashMap bdUeberigeKostenderVorhergehendenAblieferung = new HashMap<Object, BigDecimal>(); for (int i = 0; i < losablieferungDtos.length; i++) { LosablieferungDto losablieferungDto = losablieferungDtos[i]; HashMap<Integer, Object[]> hmAblieferung = new HashMap<Integer, Object[]>(); Iterator<?> it = listSollVerdichtet.keySet().iterator(); while (it.hasNext()) { Integer key = (Integer) it.next(); Object[] oNew = new Object[3]; Object[] oVorhanden = listSollVerdichtet.get(key); oNew[SOLL] = oVorhanden[SOLL]; oNew[IST] = oVorhanden[IST]; oNew[WERT] = oVorhanden[WERT]; hmAblieferung.put(key, oNew); } for (int j = 0; j < zeitenMaschine.length; j++) { BigDecimal bdIst = new BigDecimal(0.00); if (zeitenMaschine[j].getTsEnde() != null) { if (i == 0 && i == losablieferungDtos.length - 1) { if (zeitenMaschine[j].getTsEnde().before(losablieferungDto.getTAendern()) || zeitenMaschine[j].getTsEnde().after(losablieferungDtos[0].getTAendern())) { bdIst = bdIst.add(new BigDecimal(zeitenMaschine[j].getDdDauer().doubleValue())); } } else if (i == 0) { if (zeitenMaschine[j].getTsEnde().before(losablieferungDto.getTAendern())) { bdIst = bdIst.add(new BigDecimal(zeitenMaschine[j].getDdDauer().doubleValue())); } } else if (i == losablieferungDtos.length - 1) { if (zeitenMaschine[j].getTsEnde().after(losablieferungDtos[i - 1].getTAendern())) { bdIst = bdIst.add(new BigDecimal(zeitenMaschine[j].getDdDauer().doubleValue())); } } else { if (zeitenMaschine[j].getTsEnde().after(losablieferungDtos[i - 1].getTAendern()) && zeitenMaschine[j].getTsEnde().before(losablieferungDto.getTAendern())) { bdIst = bdIst.add(new BigDecimal(zeitenMaschine[j].getDdDauer().doubleValue())); } } } if (bdIst.doubleValue() > 0) { bdKostenGesamt = bdKostenGesamt.add(zeitenMaschine[j].getBdKosten()); if (hmAblieferung.containsKey(zeitenMaschine[j].getArtikelIId())) { Object[] oZeile = hmAblieferung.get(zeitenMaschine[j].getArtikelIId()); oZeile[IST] = ((BigDecimal) oZeile[IST]).add(bdIst); oZeile[WERT] = ((BigDecimal) oZeile[WERT]).add(zeitenMaschine[j].getBdKosten()); hmAblieferung.put(zeitenMaschine[j].getArtikelIId(), oZeile); } else { Object[] oZeile = new Object[3]; oZeile[SOLL] = new BigDecimal(0.00); oZeile[IST] = bdIst; oZeile[WERT] = zeitenMaschine[j].getBdKosten(); hmAblieferung.put(zeitenMaschine[j].getArtikelIId(), oZeile); } } } // Zeiten Mann for (int j = 0; j < zeitenMann.length; j++) { BigDecimal bdIst = new BigDecimal(0.00); if (zeitenMann[j].getTsEnde() != null) { if (i == 0 && i == losablieferungDtos.length - 1) { if (zeitenMann[j].getTsEnde().before(losablieferungDto.getTAendern()) || zeitenMann[j].getTsEnde().after(losablieferungDtos[0].getTAendern())) { bdIst = bdIst.add(new BigDecimal(zeitenMann[j].getDdDauer().doubleValue())); } } else if (i == 0) { if (zeitenMann[j].getTsEnde().before(losablieferungDto.getTAendern())) { bdIst = bdIst.add(new BigDecimal(zeitenMann[j].getDdDauer().doubleValue())); } } else if (i == losablieferungDtos.length - 1) { if (zeitenMann[j].getTsEnde().after(losablieferungDtos[i - 1].getTAendern())) { bdIst = bdIst.add(new BigDecimal(zeitenMann[j].getDdDauer().doubleValue())); } } else { if (zeitenMann[j].getTsEnde().after(losablieferungDtos[i - 1].getTAendern()) && zeitenMann[j].getTsEnde().before(losablieferungDto.getTAendern())) { bdIst = bdIst.add(new BigDecimal(zeitenMann[j].getDdDauer().doubleValue())); } } } if (bdIst.doubleValue() > 0) { bdKostenGesamt = bdKostenGesamt.add(zeitenMann[j].getBdKosten()); if (hmAblieferung.containsKey(zeitenMann[j].getArtikelIId())) { Object[] oZeile = hmAblieferung.get(zeitenMann[j].getArtikelIId()); oZeile[IST] = ((BigDecimal) oZeile[IST]).add(bdIst); oZeile[WERT] = ((BigDecimal) oZeile[WERT]).add(zeitenMann[j].getBdKosten()); hmAblieferung.put(zeitenMann[j].getArtikelIId(), oZeile); } else { Object[] oZeile = new Object[3]; oZeile[SOLL] = new BigDecimal(0.00); oZeile[IST] = bdIst; oZeile[WERT] = zeitenMann[j].getBdKosten(); hmAblieferung.put(zeitenMann[j].getArtikelIId(), oZeile); } } } Iterator<?> itTemp = hmAblieferung.keySet().iterator(); BigDecimal azWertDerAblieferung = new BigDecimal(0.00); while (itTemp.hasNext()) { Integer key = (Integer) itTemp.next(); Object[] oZeile = hmAblieferung.get(key); // Sollsatzgroesze ermitteln BigDecimal bdIstAblieferung = (BigDecimal) oZeile[IST]; // Vorherige uebrige Zeit dazuzaehlen if (hmUeberigeZeitderVorhergehendenAblieferung.containsKey(key)) { bdIstAblieferung = bdIstAblieferung .add((BigDecimal) hmUeberigeZeitderVorhergehendenAblieferung.get(key)); } BigDecimal bdSollAblieferung = (BigDecimal) oZeile[SOLL]; BigDecimal bdKostenAblieferung = (BigDecimal) oZeile[WERT]; if (bdUeberigeKostenderVorhergehendenAblieferung.containsKey(key)) { bdKostenAblieferung = bdKostenAblieferung .add((BigDecimal) bdUeberigeKostenderVorhergehendenAblieferung.get(key)); } if (bdSollAblieferung.doubleValue() != 0) { // Sollsatzgroesse ermitteln BigDecimal sollsatzgroesse = bdSollAblieferung .divide(losDto.getNLosgroesse(), 4, BigDecimal.ROUND_HALF_EVEN) .multiply(losablieferungDto.getNMenge()); BigDecimal maxSollsatzKosten = bdSollAblieferung.multiply(losablieferungDto.getNMenge()); BigDecimal tatsaechlicheKosten = null; if (bdKostenAblieferung.doubleValue() > maxSollsatzKosten.doubleValue()) { tatsaechlicheKosten = maxSollsatzKosten; } else { tatsaechlicheKosten = bdKostenAblieferung; } azWertDerAblieferung = azWertDerAblieferung.add(tatsaechlicheKosten); if (bdKostenAblieferung.doubleValue() > azWertDerAblieferung.doubleValue()) { bdUeberigeKostenderVorhergehendenAblieferung.put(key, bdKostenAblieferung.subtract(azWertDerAblieferung)); } } else { azWertDerAblieferung = azWertDerAblieferung.add(bdKostenAblieferung); } System.out.println(azWertDerAblieferung); } bdVerbrauchteKostenGesamt = bdVerbrauchteKostenGesamt.add(azWertDerAblieferung); // Wenn ERLEDIGT oder Ueberliefert //Den Rest hinzufuegen if (bErledigtOderUeberliefert && i == losablieferungDtos.length - 1) { BigDecimal restKosten = bdKostenGesamt.subtract(bdVerbrauchteKostenGesamt); azWertDerAblieferung = azWertDerAblieferung.add(restKosten); } if (losablieferungDto.getNMenge().doubleValue() != 0) { azWertDerAblieferung = azWertDerAblieferung.divide(losablieferungDto.getNMenge(), 4, BigDecimal.ROUND_HALF_EVEN); } Losablieferung losablieferung = em.find(Losablieferung.class, losablieferungDto.getIId()); if (losablieferung == null) { throw new EJBExceptionLP(EJBExceptionLP.FEHLER_BEI_FINDBYPRIMARYKEY, ""); } losablieferung.setNArbeitszeitwert(azWertDerAblieferung); losablieferung.setNArbeitszeitwertdetailliert(azWertDerAblieferung); } } catch (RemoteException ex1) { throwEJBExceptionLPRespectOld(ex1); } }