📄 invoiceservices.java
字号:
GenericValue userLogin = (GenericValue) context.get("userLogin"); String returnId= (String) context.get("returnId"); List receipts = (List) context.get("shipmentReceiptsToBill"); String errorMsg = "Error creating invoice for return [" + returnId + "]. "; List invoicesCreated = new ArrayList(); try { // get the return header GenericValue returnHeader = delegator.findByPrimaryKey("ReturnHeader", UtilMisc.toMap("returnId", returnId)); // set the invoice data Map input = UtilMisc.toMap("invoiceTypeId", "CUST_RTN_INVOICE", "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("billingAccountId", returnHeader.get("billingAccountId")); input.put("userLogin", userLogin); // call the service to create the invoice Map 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, 2); for (Iterator iter = receipts.iterator(); iter.hasNext(); ) { GenericValue receipt = (GenericValue) iter.next(); // we need the related return item and product GenericValue returnItem = receipt.getRelatedOneCache("ReturnItem"); GenericValue product = returnItem.getRelatedOneCache("Product"); // extract the return price as a big decimal for convenience BigDecimal returnPrice = returnItem.getBigDecimal("returnPrice"); // determine invoice item type from the return item type String invoiceItemTypeId = getInvoiceItemType(delegator, returnItem.getString("returnItemTypeId"), "CUST_RTN_INVOICE", null); if (invoiceItemTypeId == null) { return ServiceUtil.returnError(errorMsg + "No known invoice item type for the return item type [" + returnItem.getString("returnItemTypeId") + "]"); } // create the invoice item for this shipment receipt input = UtilMisc.toMap("invoiceId", invoiceId, "invoiceItemTypeId", invoiceItemTypeId, "quantity", receipt.get("quantityAccepted")); input.put("invoiceItemSeqId", "" + invoiceItemSeqId); // turn the int into a string with ("" + int) hack input.put("amount", returnItem.get("returnPrice")); // this service requires Double input.put("productId", returnItem.get("productId")); 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("shipmentReceiptId", receipt.get("receiptId")); input.put("quantity", receipt.get("quantityAccepted")); input.put("amount", returnItem.get("returnPrice")); // this service requires Double input.put("userLogin", userLogin); serviceResults = dispatcher.runSync("createReturnItemBilling", input); if (ServiceUtil.isError(serviceResults)) { return ServiceUtil.returnError(errorMsg, null, null, serviceResults); } if (Debug.verboseOn()) { Debug.logVerbose("Creating Invoice Item with amount " + returnPrice + " and quantity " + receipt.getBigDecimal("quantityAccepted") + " for shipment receipt [" + receipt.getString("receiptId") + "]", module); } // increment the seqId counter after creating the invoice item and return item billing invoiceItemSeqNum += 1; invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, 2); // keep a running total (note: a returnItem may have many receipts. hence, the promised total quantity is the receipt quantityAccepted + quantityRejected) BigDecimal actualAmount = returnPrice.multiply(receipt.getBigDecimal("quantityAccepted")).setScale(decimals, rounding); BigDecimal promisedAmount = returnPrice.multiply(receipt.getBigDecimal("quantityAccepted").add(receipt.getBigDecimal("quantityRejected"))).setScale(decimals, rounding); 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 adjustments = returnItem.getRelatedCache("ReturnAdjustment"); for (Iterator adjIter = adjustments.iterator(); adjIter.hasNext(); ) { GenericValue adjustment = (GenericValue) adjIter.next(); // determine invoice item type from the return item type invoiceItemTypeId = getInvoiceItemType(delegator, adjustment.getString("returnAdjustmentTypeId"), "CUST_RTN_INVOICE", null); if (invoiceItemTypeId == null) { return ServiceUtil.returnError(errorMsg + "No known invoice item type for the return adjustment type [" + adjustment.getString("returnAdjustmentTypeId") + "]"); } // prorate the adjustment amount by the returned amount; do not round ratio BigDecimal ratio = receipt.getBigDecimal("quantityAccepted").divide(returnItem.getBigDecimal("returnQuantity"), 100, rounding); BigDecimal 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", new Double(1.0)); input.put("amount", new Double(amount.doubleValue())); 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("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, 2); // 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 adjustments = returnHeader.getRelatedByAndCache("ReturnAdjustment", UtilMisc.toMap("returnItemSeqId", "_NA_")); for (Iterator iter = adjustments.iterator(); iter.hasNext(); ) { GenericValue adjustment = (GenericValue) iter.next(); // determine invoice item type from the return item type String invoiceItemTypeId = getInvoiceItemType(delegator, adjustment.getString("returnAdjustmentTypeId"), "CUST_RTN_INVOICE", null); if (invoiceItemTypeId == null) { return ServiceUtil.returnError(errorMsg + "No known invoice item type for the return adjustment type [" + adjustment.getString("returnAdjustmentTypeId") + "]"); } // prorate the adjustment amount by the 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", new Double(1.0)); input.put("amount", new Double(amount.doubleValue())); 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, 2); } // Set the invoice to READY serviceResults = dispatcher.runSync("setInvoiceStatus", UtilMisc.toMap("invoiceId", invoiceId, "statusId", "INVOICE_READY", "userLogin", userLogin)); if (ServiceUtil.isError(serviceResults)) { return ServiceUtil.returnError(errorMsg, null, null, serviceResults); } // return the invoiceId Map results = ServiceUtil.returnSuccess(); 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()); } } public static Map checkInvoicePaymentApplications(DispatchContext ctx, Map context) { GenericDelegator delegator = ctx.getDelegator(); LocalDispatcher dispatcher = ctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); if (decimals == -1 || rounding == -1) { return ServiceUtil.returnError("Arithmetic properties for Invoice services not configured properly. Cannot proceed."); } String invoiceId = (String) context.get("invoiceId"); List paymentAppl = null; try { paymentAppl = delegator.findByAnd("Payme
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -