Package org.ofbiz.accounting.agreement

Source Code of org.ofbiz.accounting.agreement.AgreementServices

/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*******************************************************************************/

package org.ofbiz.accounting.agreement;

import java.math.BigDecimal;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javolution.util.FastList;

import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.UtilNumber;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.GenericEntity;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.entity.util.EntityUtil;
import org.ofbiz.service.DispatchContext;
import org.ofbiz.service.ModelService;
import org.ofbiz.service.ServiceUtil;

/**
* Services for Agreement (Accounting)
*/

public class AgreementServices {

    public static final String module = AgreementServices.class.getName();
    // set some BigDecimal properties
    private static BigDecimal ZERO = BigDecimal.ZERO;
    private static int decimals = -1;
    private static int rounding = -1;
    static {
        decimals = UtilNumber.getBigDecimalScale("invoice.decimals");
        rounding = UtilNumber.getBigDecimalRoundingMode("invoice.rounding");

        // set zero to the proper scale
        if (decimals != -1) ZERO = ZERO.setScale(decimals, rounding);
    }
    public static final String resource = "AccountingUiLabels";

    /**
     * Determines commission receiving parties and amounts for the provided product, price, and quantity
     * @param ctx The DispatchContext that this service is operating in.
     * @param context Map containing the input parameters.
     *      productId   String      Product Id
     *      invoiceItemTypeId   String      Invoice Type
     *      amount      BigDecimal  Entire amount
     *      quantity    BigDecimal  Quantity
     * @return Map with the result of the service, the output parameters.
     *      commissions List        List of Maps each containing
     *              partyIdFrom     String  commission paying party
     *              partyIdTo       String  commission receiving party
     *              commission      BigDecimal  Commission
     *              days            Long    term days
     *              currencyUomId   String  Currency
     *              productId       String  Product Id
     */
    public static Map<String, Object> getCommissionForProduct(DispatchContext ctx, Map<String, Object> context) {
        Delegator delegator = ctx.getDelegator();
        Locale locale = (Locale) context.get("locale");
        String errMsg = null;
        List<Map<String, Object>> commissions = FastList.newInstance();

        try {
            BigDecimal amount = ((BigDecimal)context.get("amount"));
            BigDecimal quantity = (BigDecimal)context.get("quantity");
            quantity = quantity == null ? BigDecimal.ONE : quantity;
            boolean negative = amount.signum() < 0;
            // Ensure that price and quantity are positive since the terms may not be linear.
            amount = amount.abs();
            quantity = quantity.abs();
            String productId = (String) context.get("productId");
            String invoiceItemTypeId = (String) context.get("invoiceItemTypeId");
            String invoiceItemSeqId = (String) context.get("invoiceItemSeqId");
            String invoiceId = (String) context.get("invoiceId");

            // Collect agreementItems applicable to this orderItem/returnItem
            // TODO: partyIds should be part of this query!
            List<GenericValue> agreementItems = delegator.findByAndCache("AgreementItemAndProductAppl", UtilMisc.toMap(
                    "productId", productId,
                    "agreementItemTypeId", "AGREEMENT_COMMISSION"));
            // Try the first available virtual product if this is a variant product
            if (agreementItems.size() == 0) {
                List<GenericValue> productAssocs = delegator.findByAndCache("ProductAssoc", UtilMisc.toMap(
                        "productIdTo", productId,
                        "productAssocTypeId", "PRODUCT_VARIANT"));
                productAssocs = EntityUtil.filterByDate(productAssocs);
                if (productAssocs.size() > 0) {
                    GenericEntity productAssoc = EntityUtil.getFirst(productAssocs);
                    agreementItems = delegator.findByAndCache("AgreementItemAndProductAppl", UtilMisc.toMap(
                            "productId", productAssoc.getString("productId"),
                            "agreementItemTypeId", "AGREEMENT_COMMISSION"));
                }
            }
            // this is not very efficient if there were many
            agreementItems = EntityUtil.filterByDate(agreementItems);

            for (GenericValue agreementItem : agreementItems) {
                List<GenericValue> terms = delegator.findByAndCache("AgreementTerm", UtilMisc.toMap(
                        "agreementId", agreementItem.getString("agreementId"),
                        "agreementItemSeqId", agreementItem.getString("agreementItemSeqId"),
                        "invoiceItemTypeId", invoiceItemTypeId));
                if (terms.size() > 0) {
                    BigDecimal commission = ZERO;
                    BigDecimal min = new BigDecimal("-1e12");   // Limit to 1 trillion commission
                    BigDecimal max = new BigDecimal("1e12");

                    // number of days due for commission, which will be the lowest termDays of all the AgreementTerms
                    long days = -1;
                    for (GenericValue term : terms) {
                        String termTypeId = term.getString("termTypeId");
                        BigDecimal termValue = term.getBigDecimal("termValue");
                        if (termValue != null) {
                            if (termTypeId.equals("FIN_COMM_FIXED")) {
                                commission = commission.add(termValue);
                            } else if (termTypeId.equals("FIN_COMM_VARIABLE")) {
                                // if variable percentage commission, need to divide by 100, because 5% is stored as termValue of 5.0
                                commission = commission.add(termValue.multiply(amount).divide(new BigDecimal("100"), 12, rounding));
                            } else if (termTypeId.equals("FIN_COMM_MIN")) {
                                min = termValue;
                            } else if (termTypeId.equals("FIN_COMM_MAX")) {
                                max = termValue;
                            }
                            // TODO: Add other type of terms and handling here
                        }

                        // see if we need to update the number of days for paying commission
                        Long termDays = term.getLong("termDays");
                        if (termDays != null) {
                            // if days is greater than zero, then it has been set with another value, so we use the lowest term days
                            // if days is less than zero, then it has not been set yet.
                            if (days > 0) {
                                days = Math.min(days, termDays.longValue());
                            } else {
                                days = termDays.longValue();
                            }
                        }
                    }
                    if (commission.compareTo(min) < 0)
                        commission = min;
                    if (commission.compareTo(max) > 0)
                        commission = max;
                    commission = negative ? commission.negate() : commission;
                    commission = commission.setScale(decimals, rounding);

                    Map<String, Object> partyCommissionResult = UtilMisc.toMap(
                            "partyIdFrom", agreementItem.getString("partyIdFrom"),
                            "partyIdTo", agreementItem.getString("partyIdTo"),
                            "invoiceItemSeqId", invoiceItemSeqId,
                            "invoiceId", invoiceId,
                            "commission", commission,
                            "quantity", quantity,
                            "currencyUomId", agreementItem.getString("currencyUomId"),
                            "productId", productId);
                    if (days >= 0) {
                        partyCommissionResult.put("days", Long.valueOf(days));
                    }
                    if (!commissions.contains(partyCommissionResult)) {
                        commissions.add(partyCommissionResult);
                    }
                }
            }
        } catch (GenericEntityException e) {
            Debug.logWarning(e, module);
            Map<String, String> messageMap = UtilMisc.toMap("errMessage", e.getMessage());
            errMsg = UtilProperties.getMessage("CommonUiLabels", "CommonDatabaseProblem", messageMap, locale);
            return ServiceUtil.returnError(errMsg);
        }
        return UtilMisc.toMap(
                "commissions", commissions,
                ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS);
    }
}
TOP

Related Classes of org.ofbiz.accounting.agreement.AgreementServices

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.