com.aiatss.coast.pmm.application.service.agreement.PolicyServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.aiatss.coast.pmm.application.service.agreement.PolicyServiceImpl.java

Source

/**
 *-------------------------------------------------<br>
* Copyright (c) 2015-2017 AIA . All Rights Reserved.  <br>
 *-------------------------------------------------<br>
 * Project Name   : <code>COAST_PMM</code><br>
 * @author: Luo,Mark-S
 * @version: 1.0
 * @see: 
 * Description: find, create policy* data
 * Revised Records:<br>
 */

package com.aiatss.coast.pmm.application.service.agreement;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.aiatss.coast.common.biztransaction.application.service.BizTransactionManager;
import com.aiatss.coast.common.biztransaction.domain.model.BizTransaction;
import com.aiatss.coast.common.infrastructure.persistent.BaseContext;
import com.aiatss.coast.common.infrastructure.persistent.util.IBeanUtils;
import com.aiatss.coast.common.util.date.DateTimeUtil;
import com.aiatss.coast.common.util.exception.BusinessException;
import com.aiatss.coast.common.util.exception.ExceptionConstants;
import com.aiatss.coast.common.util.exception.ParameterException;
import com.aiatss.coast.pmm.application.service.party.OrganizationService;
import com.aiatss.coast.pmm.application.service.product.ProductService;
import com.aiatss.coast.pmm.common.DataTypeConst;
import com.aiatss.coast.pmm.domain.model.agreement.Policy;
import com.aiatss.coast.pmm.domain.model.agreement.PolicyAttachment;
import com.aiatss.coast.pmm.domain.model.agreement.PolicyPkgScheme;
import com.aiatss.coast.pmm.domain.model.agreement.PolicyPkgSchemeDetail;
import com.aiatss.coast.pmm.domain.model.agreement.PolicyProduct;
import com.aiatss.coast.pmm.domain.model.agreement.PolicyProductAge;
import com.aiatss.coast.pmm.domain.model.agreement.PolicyProductAttachment;
import com.aiatss.coast.pmm.domain.model.agreement.PolicyProductBenefit;
import com.aiatss.coast.pmm.domain.model.agreement.PolicyProductBenefitSum;
import com.aiatss.coast.pmm.domain.model.agreement.PolicyProductPlan;
import com.aiatss.coast.pmm.domain.model.agreement.PolicyProductPremiumRate;
import com.aiatss.coast.pmm.domain.model.agreement.PolicyProductProducer;
import com.aiatss.coast.pmm.domain.model.agreement.PolicyProductRepository;
import com.aiatss.coast.pmm.domain.model.agreement.PolicyRepository;
import com.aiatss.coast.pmm.domain.model.agreement.PolicyYear;
import com.aiatss.coast.pmm.domain.model.party.MemberRepository;
import com.aiatss.coast.pmm.domain.model.product.PkgResolution;
import com.aiatss.coast.pmm.domain.model.product.Product;
import com.aiatss.coast.pmm.domain.model.product.ProductAge;
import com.aiatss.coast.pmm.domain.model.product.ProductBenefit;
import com.aiatss.coast.pmm.domain.model.product.ProductBenefitSum;
import com.aiatss.coast.pmm.domain.model.product.ProductPlan;
import com.aiatss.coast.pmm.domain.model.product.ProductPlanCoverage;

@Service(value = "policyService")
public class PolicyServiceImpl implements PolicyService {

    @Autowired
    @Qualifier(value = "policyRepository")
    private PolicyRepository policyRepository;

    @Autowired
    @Qualifier(value = "verifyPolicyService")
    private VerifyPolicyService verifyPolicyService;

    @Autowired
    @Qualifier(value = "policyProductRepository")
    private PolicyProductRepository policyProductRepository;

    @Autowired
    @Qualifier(value = "policyProductService")
    private PolicyProductService policyProductService;

    @Autowired
    @Qualifier(value = "productService")
    private ProductService productService;

    @Autowired
    @Qualifier(value = "organizationService")
    private OrganizationService organizationService;

    @Autowired
    @Qualifier(value = "baseContext")
    BaseContext baseContext;

    @Autowired
    @Qualifier(value = "bizTransactionManager")
    BizTransactionManager bizTransactionManager;

    @Autowired
    @Qualifier(value = "memberRepository")
    MemberRepository memberRepository;

    @Override
    public Policy persistPolicy(Policy policy) {
        boolean isNew = false;
        if (policy.getId() == null) {
            // new
            isNew = true;
        }

        // policy basic
        policyRepository.persistPolicy(policy);

        // policy year
        List<PolicyYear> policyYears = policy.getPolicyYears();
        if (policyYears != null) {
            for (PolicyYear policyYear : policyYears) {
                persistPolicyYear(policyYear);
            }
        }

        // attachment
        PolicyAttachment policyAttachment = policy.getPolicyAttachment();
        if (null != policyAttachment) {
            if (isNew) {
                // new
                createPolicyAttachment(policyAttachment);
            } else {
                // update
                updatePolicyAttachment(policyAttachment);
            }
        }

        // policyProduct
        List<PolicyProduct> policyProducts = policy.getPolicyProducts();
        if (policyProducts != null) {
            for (PolicyProduct policyProduct : policyProducts) {
                this.policyProductService.persistPolicyProduct(policyProduct);
            }
        }
        // pkg plan
        List<PolicyPkgScheme> policyPkgPlans = policy.getPolicyPkgSchemes();
        if (policyPkgPlans != null) {
            for (PolicyPkgScheme policyPkgPlan : policyPkgPlans) {
                this.persistPolicyPkgScheme(policyPkgPlan);

            }
        }

        return policy;
    }

    private void buildPolicyYear(Policy policy) {
        PolicyYear policyYear = new PolicyYear();
        policyYear.setAnniversaryDate(policy.getAnniversaryDate());
        policyYear.setFromDate(policy.getInitialEffectiveDate());
        policyYear.setPolicyYear(1);
        Date increaseOneYears = DateUtils.addYears(policy.getAnniversaryDate(), 1);
        Date decreaseOneDate = DateUtils.addDays(increaseOneYears, -1);
        policyYear.setToDate(decreaseOneDate);
        List<PolicyYear> policyYears = new ArrayList<PolicyYear>();
        policyYears.add(policyYear);
        policy.setPolicyYears(policyYears);
    }

    @Override
    public PolicyYear persistPolicyYear(PolicyYear policyYear) {
        policyRepository.persistPolicyYear(policyYear);
        return policyYear;
    }

    @Override
    public PolicyPkgScheme persistPolicyPkgScheme(PolicyPkgScheme policyPkgPlan) {
        // CreatePackagePolicyPlan
        this.policyRepository.persistPackagePolicyPlan(policyPkgPlan);

        // create PolicyPkgPlanDetail
        List<PolicyPkgSchemeDetail> policyPkgPlanDetails = policyPkgPlan.getPolicyPkgSchemeDetails();
        for (PolicyPkgSchemeDetail policyPkgPlanDetail : policyPkgPlanDetails) {
            this.persistPolicyPkgPlanDetail(policyPkgPlanDetail);
        }
        return policyPkgPlan;
    }

    @Override
    public Policy findPolicyByNo(String policyNo) {
        return this.policyRepository.findByPolicyNo(policyNo);

    }

    @Override
    public boolean isPackageProduct(Policy policy) {

        List<PolicyPkgScheme> policyPkgPlans = policy.getPolicyPkgSchemes();
        if (policyPkgPlans != null && !policyPkgPlans.isEmpty() && policyPkgPlans.get(0).getPkgProductId() > 0) {
            return true;
        }
        return false;
    }

    @Override
    public boolean isLifeProduct(PolicyProduct policyProduct) {
        if (policyProduct == null) {
            return false;
        }
        return productService.isLifeProduct(policyProduct.getProductId());
    }

    @Override
    public Policy createPolicyForNB(Policy policy) {
        baseContext.setTransactionDate(baseContext.getTransactionDate());
        BizTransaction bizTransaction = bizTransactionManager.beginTransaction("1");
        if (this.isPackageProduct(policy)) {
            createPkgPolicy(policy);
        } else {
            this.createTailorMadePolicy(policy);
        }
        bizTransactionManager.commit(bizTransaction);
        return policy;
    }

    @Override
    public List<PolicyPkgScheme> findPolicyPkgPlansByPolicyId(Integer policyId) {
        List<PolicyPkgScheme> policyPkgSchemes = policyRepository.findPolicyPkgPlansByPolicyId(policyId);
        for (PolicyPkgScheme policyPkgScheme : policyPkgSchemes) {
            List<PolicyPkgSchemeDetail> findPolicyPkgPlanDetails = this.policyRepository
                    .findPolicyPkgPlanDetails(policyPkgScheme.getPolicyPkgSchemeId());
            policyPkgScheme.setPolicyPkgSchemeDetails(findPolicyPkgPlanDetails);
        }
        return policyPkgSchemes;
    }

    @Override
    public PolicyAttachment createPolicyAttachment(PolicyAttachment policyAttachment) {
        this.policyRepository.createPolicyAttachment(policyAttachment);
        return policyAttachment;
    }

    private PolicyAttachment updatePolicyAttachment(PolicyAttachment policyAttachment) {
        this.policyRepository.updatePolicyAttachment(policyAttachment);
        return policyAttachment;
    }

    @Override
    public PolicyPkgSchemeDetail persistPolicyPkgPlanDetail(PolicyPkgSchemeDetail policyPkgPlanDetail) {
        policyRepository.persistPolicyPkgPlanDetail(policyPkgPlanDetail);
        return policyPkgPlanDetail;
    }

    @Override
    public Policy findPolicyById(Integer policyId) {
        Policy policy = policyRepository.findPolicyById(policyId); // NOSONAR
        return policy;
    }

    @Override
    public Policy createTailorMadePolicy(Policy policy) {
        setPolicyTypeAsTailorMade(policy);

        buildPolicyYear(policy);

        // set default value
        setPolicyDefaultValue(policy);

        // verify policy
        this.verifyPolicyService.verifyTailorMadePolicy(policy);

        baseContext.setTransactionDate(baseContext.getTransactionDate());
        BizTransaction bizTransaction = bizTransactionManager.beginTransaction("1");

        // create policy
        this.persistPolicy(policy);

        bizTransactionManager.commit(bizTransaction);
        return policy;
    }

    @Override
    public Policy createPkgPolicy(Policy policy) {

        setPolicyTypeAsPackage(policy);

        // build full structure of policy since pkg sub products need to be
        // built
        buildPkgPolicyProductsByPkgProductCode(policy);

        buildPolicyYear(policy);

        buildPkgSchemeDetailConnectionToPolicyPlan(policy);

        // set default value
        setPolicyDefaultValue(policy);

        verifyPolicyService.verifyPackagedPolicy(policy);

        // createPolicy
        this.persistPolicy(policy);

        return policy;
    }

    /**
     * Description: Set Policy Type As Package
     * 
     * @param policy
     */
    private void setPolicyTypeAsPackage(Policy policy) {
        policy.setPolicyCategory(DataTypeConst.POLICYTYPE_PACKAGE);
    }

    /**
     * Description: Set Policy Type As TailorMade
     * 
     * @param policy
     */
    private void setPolicyTypeAsTailorMade(Policy policy) {
        policy.setPolicyCategory(DataTypeConst.POLICYTYPE_TAILORMADE);
    }

    @Override
    public void buildPkgPolicyProductsByPkgProductCode(Policy policy) {
        // assume that user input product info should be store in below
        // policyProducts
        List<PolicyProduct> policyProducts = policy.getPolicyProducts();
        if (policyProducts == null || policyProducts.isEmpty()) {
            throw new ParameterException("Policy Product information is required.");
        }
        PolicyProduct userInputPolicyProduct = policyProducts.get(0);

        // assume that user input producer info should be store in below
        List<PolicyProductProducer> inputPolicyProductProducers = userInputPolicyProduct
                .getPolicyProductProducers();
        if (inputPolicyProductProducers == null || inputPolicyProductProducers.isEmpty()) {
            throw new ParameterException("Policy Producer information is required.");
        }

        List<PolicyPkgScheme> pkgPlans = policy.getPolicyPkgSchemes();

        Integer pkgProductId = pkgPlans.get(0).getPkgProductId();
        // build package products and detail:
        policyProducts = buildPkgSubProductsDetail(userInputPolicyProduct, inputPolicyProductProducers, pkgPlans,
                pkgProductId);
        policy.setPolicyProducts(policyProducts);
    }

    /**
     * Description  Build package product detail by input product & producers & package plan & package product ID
     * @param userInputPolicyProduct
     * @param inputPolicyProductProducers
     * @param pkgSchemes
     * @param pkgProductId
     * @return List<PolicyProduct>
     */
    @Override
    public List<PolicyProduct> buildPkgSubProductsDetail(PolicyProduct userInputPolicyProduct,
            List<PolicyProductProducer> inputPolicyProductProducers, List<PolicyPkgScheme> pkgSchemes,
            Integer pkgProductId) {
        List<PolicyProduct> policyProducts = new ArrayList<PolicyProduct>();
        PkgResolution pkgProduct = productService.findProductDetailByPkgProductId(pkgProductId);

        if (pkgProduct == null) {
            throw new ParameterException(ExceptionConstants.PMMException.NO_SUB_PRODUCT_FOUND_FOR_PKG_PRODUCT_CODE);
        }

        List<Product> products = pkgProduct.getProducts();
        for (PolicyPkgScheme pkgPlan : pkgSchemes) {
            if (!pkgPlan.getStatus().equals(DataTypeConst.STATUS_T)) { // NOSONAR
                List<PolicyPkgSchemeDetail> detail = pkgPlan.getPolicyPkgSchemeDetails();
                for (PolicyPkgSchemeDetail policyPkgPlanDetail : detail) {
                    buildPkgProductAndPlan(userInputPolicyProduct, inputPolicyProductProducers,
                            policyPkgPlanDetail.getProductId(), policyPkgPlanDetail.getBenefitPlanCode(),
                            policyProducts, products);
                }
            }
        }
        return policyProducts;
    }

    /**
     * Description  Build package scheme of full products structure from $inputPolicyProduct
     * & $inputPolicyProductProducers based on the stand $policyProducts (match
     * $productId and $benefitPlanCode . $policyProducts is the output value.
     * @param inputPolicyProduct
     * @param inputPolicyProductProducers
     * @param productId
     * @param benefitPlanCode
     * @param policyProducts
     * @param products
     */
    private void buildPkgProductAndPlan(PolicyProduct inputPolicyProduct,
            List<PolicyProductProducer> inputPolicyProductProducers, Integer productId, String benefitPlanCode,
            List<PolicyProduct> policyProducts, List<Product> products) {
        boolean newProduct = true;
        boolean newPlan = true;
        PolicyProduct policyProduct = null;
        Product product = null;
        for (PolicyProduct policyProd : policyProducts) {
            if (policyProd.getProductId() == productId) {
                newProduct = false;
                policyProduct = policyProd;
                newPlan = isNewPlan(benefitPlanCode, policyProd);
            }
        }
        if (newProduct) {
            // create a new policyProduct
            policyProduct = new PolicyProduct();
            fillInputPolicyProductForPkg(inputPolicyProduct, policyProduct);
            policyProduct.setProductId(productId);
            policyProduct.setTransactionDate(DateTimeUtil.getCurrentDateTime());
            policyProducts.add(policyProduct);
            PolicyProductAttachment policyProductAttachment = new PolicyProductAttachment();
            for (Product prod : products) {
                // find standard product
                if (policyProduct.getProductId().equals(prod.getProductId())) {
                    product = prod;
                    //set policyProduct for product.
                    policyProduct.setCurrencyId(product.getCurrencyId());
                    policyProduct.setReinsuranceSchemeId(product.getReinsuranceSchemeId());
                    policyProduct.setPremiumServiceTaxPct(product.getPremiumTaxPct());
                    policyProduct.setAccountId(product.getAccountId());
                    policyProduct.setPremiumServiceTaxAmt(product.getPremiumTax());
                    policyProduct.setLocalValuationParmId(product.getLocalValuationParmId());
                    policyProduct.setValuationParmId(product.getValuationParmId());
                    policyProduct.setLicenseType(product.getLicenseType());

                    //set policyProductAttachment
                    policyProductAttachment.setPolicyProductId(policyProduct.getPolicyProductId());
                    policyProductAttachment.setRlobId(product.getRlobId());
                    policyProduct.setPolicyProductAttachment(policyProductAttachment);
                    // create age from standard
                    buildAge(policyProduct, prod);
                    // create producers
                    buildProducer(inputPolicyProductProducers, policyProduct);
                    break;
                }
            }
        }
        if (newPlan) {
            buildNewPlan(benefitPlanCode, policyProduct, product);
        }

    }

    private boolean isNewPlan(String benefitPlanCode, PolicyProduct policyProd) {
        boolean newPlan = true;
        for (PolicyProductPlan plan : policyProd.getPolicyProductPlans()) {
            if (plan.getBenefitPlanCode().equals(benefitPlanCode)) {
                newPlan = false;
                break;
            }
        }
        return newPlan;
    }

    private void buildProducer(List<PolicyProductProducer> policyProductProducers, PolicyProduct policyProduct) {
        List<PolicyProductProducer> producers = IBeanUtils.copyPropertiesForList(policyProductProducers,
                PolicyProductProducer.class);
        for (PolicyProductProducer policyProductProducer : producers) {
            policyProductProducer.setProductId(policyProduct.getProductId());
            policyProductProducer.setPolicyProductId(policyProduct.getPolicyProductId());
        }
        policyProduct.setPolicyProductProducers(producers);
    }

    private void buildAge(PolicyProduct policyProduct, Product prod) {
        for (ProductAge age : prod.getProductAges()) {
            PolicyProductAge policyProductAge = IBeanUtils.copyProperties(age, PolicyProductAge.class);
            policyProductAge.setEffectiveDate(policyProduct.getEffectiveDate());
            policyProductAge.setTransactionDate(DateTimeUtil.getCurrentDateTime());
            if (policyProduct.getPolicyProductAges() == null) {
                policyProduct.setPolicyProductAges(new ArrayList<PolicyProductAge>());
            }
            policyProduct.getPolicyProductAges().add(policyProductAge);
        }
    }

    private void buildNewPlan(String benefitPlanCode, PolicyProduct policyProduct, Product product) {
        for (ProductPlan plan : product.getProductPlans()) {
            // find standard plan
            if (plan.getBenefitPlanCode().equals(benefitPlanCode)) {

                // create policy plan from standard plan
                PolicyProductPlan policyProductPlan = IBeanUtils.copyProperties(plan, PolicyProductPlan.class);
                policyProductPlan.setEffectiveDate(policyProduct.getEffectiveDate());
                policyProductPlan.setTransactionDate(DateTimeUtil.getCurrentDateTime());
                createPolicyPremiumRates(plan, policyProductPlan);

                // create policy benefit
                createPolicyProductBenefit(plan, policyProductPlan);

                if (policyProduct.getPolicyProductPlans() == null) {
                    policyProduct.setPolicyProductPlans(new ArrayList<PolicyProductPlan>());
                }
                policyProduct.getPolicyProductPlans().add(policyProductPlan);
                break;
            }
        }
    }

    private void createPolicyProductBenefit(ProductPlan plan, PolicyProductPlan policyProductPlan) {
        for (ProductBenefit productBenefit : plan.getProductBenefits()) {
            PolicyProductBenefit policyBenefit = IBeanUtils.copyProperties(productBenefit,
                    PolicyProductBenefit.class);
            policyBenefit.setEffectiveDate(policyProductPlan.getEffectiveDate());
            policyBenefit.setTransactionDate(DateTimeUtil.getCurrentDateTime());
            if (policyProductPlan.getPolicyProductBenefits() == null) {
                policyProductPlan.setPolicyProductBenefits(new ArrayList<PolicyProductBenefit>());
            }
            policyProductPlan.getPolicyProductBenefits().add(policyBenefit);
            // create policy benefit summary
            for (ProductBenefitSum productBenefitSum : productBenefit.getProductBenefitSums()) {
                PolicyProductBenefitSum policyProductBenefitSum = IBeanUtils.copyProperties(productBenefitSum,
                        PolicyProductBenefitSum.class);
                productBenefitSum.setEffectiveDate(policyBenefit.getEffectiveDate());
                productBenefitSum.setTransactionDate(DateTimeUtil.getCurrentDateTime());
                if (policyBenefit.getPolicyProductBenefitSums() == null) {
                    policyBenefit.setPolicyProductBenefitSums(new ArrayList<PolicyProductBenefitSum>());
                }
                policyBenefit.getPolicyProductBenefitSums().add(policyProductBenefitSum);
            }
        }
    }

    private void createPolicyPremiumRates(ProductPlan plan, PolicyProductPlan policyProductPlan) {
        // create policy premium rate
        List<ProductPlanCoverage> coverages = plan.getProductPlanCoverages();
        if (coverages != null) {
            List<PolicyProductPremiumRate> rates = new ArrayList<PolicyProductPremiumRate>();
            for (ProductPlanCoverage productPlanCoverage : coverages) {
                PolicyProductPremiumRate rate = new PolicyProductPremiumRate();
                rate.setEffectiveDate(plan.getEffectiveDate());
                rate.setTransactionDate(DateTimeUtil.getCurrentDateTime());
                rate.setProductId(plan.getProductId());
                rate.setStatus("A");
                rate.setEffectiveDate(policyProductPlan.getEffectiveDate());
                rate.setCoverageCode(productPlanCoverage.getCoverageCode());
                rate.setModalPremium(new BigDecimal(0));
                rates.add(rate);
            }
            policyProductPlan.setPolicyProductPremiumRates(rates);
        }
    }

    private void fillInputPolicyProductForPkg(PolicyProduct policyProductFrom, PolicyProduct policyProductTo) {
        // a. User can edit below package product information and copy them to
        // sub product level
        policyProductTo.setInitialEffectiveDate(policyProductFrom.getInitialEffectiveDate());
        policyProductTo.setEffectiveDate(policyProductFrom.getEffectiveDate());
        policyProductTo.setCurrencyId(policyProductFrom.getCurrencyId());
        // policyProductTo.setBizType(policyProductFrom.getBizType())
        policyProductTo.setRenewType(policyProductFrom.getRenewType());
        policyProductTo.setBizSource(policyProductFrom.getBizSource());
        policyProductTo.setChannelInd(policyProductFrom.getChannelInd());
        policyProductTo.setCommissionId(policyProductFrom.getCommissionId());
        policyProductTo.setEnrollPeriodDay(policyProductFrom.getEnrollPeriodDay());
        policyProductTo.setEnrollPeriodMonth(policyProductFrom.getEnrollPeriodMonth());
        policyProductTo.setEnrollPeriodYear(policyProductFrom.getEnrollPeriodYear());
        policyProductTo.setBillType(policyProductFrom.getBillType());
        policyProductTo.setBillPlanId(policyProductFrom.getBillPlanId());
        //  bill mode is required too but not in FS // NOSONAR
        policyProductTo.setBillMode(policyProductFrom.getBillMode());
        // premium rate is required too but not in FS // NOSONAR
        policyProductTo.setPremiumRateType(policyProductFrom.getPremiumRateType());
        // b. For sub product, user can edit below fields:
        policyProductTo.setAccountId(policyProductFrom.getAccountId());
        if (StringUtils.isBlank(policyProductTo.getBizType())) {
            policyProductTo.setBizType(policyProductFrom.getBizType());
        }
        policyProductTo.setReinsuranceSchemeId(policyProductFrom.getReinsuranceSchemeId());
        policyProductTo.setValuationParmId(policyProductFrom.getValuationParmId());
    }

    @Override
    public void buildPkgSchemeDetailConnectionToPolicyPlan(Policy policy) {

        // pkg plan
        List<PolicyPkgScheme> policyPkgPlans = policy.getPolicyPkgSchemes();

        if (policyPkgPlans != null) {
            for (PolicyPkgScheme policyPkgPlan : policyPkgPlans) {
                for (PolicyPkgSchemeDetail detail : policyPkgPlan.getPolicyPkgSchemeDetails()) {
                    PolicyProductPlan policyProductPlan = findPolicyProductPlanById(policy, detail);
                    detail.setPolicyProductPlan(policyProductPlan);
                    detail.setPolicyProductPlanId(policyProductPlan.getPolicyProductPlanId());
                }
            }
        }
    }

    private PolicyProductPlan findPolicyProductPlanById(Policy policy, PolicyPkgSchemeDetail policyPkgPlanDetail) {

        String PlanCode = policyPkgPlanDetail.getBenefitPlanCode(); // NOSONAR
        Integer PlanProductId = policyPkgPlanDetail.getProductId(); // NOSONAR

        List<PolicyProduct> policyProducts = policy.getPolicyProducts();

        for (PolicyProduct policyProduct : policyProducts) {

            List<PolicyProductPlan> policyProductPlans = policyProduct.getPolicyProductPlans();

            for (PolicyProductPlan policyProductPlan : policyProductPlans) {

                if (PlanCode.equals(policyProductPlan.getBenefitPlanCode())
                        && PlanProductId.equals(policyProductPlan.getProductId())) {

                    // returnpolicyProductPlanId =
                    // policyProductPlan.getPolicyProductPlanId(); // NOSONAR
                    return policyProductPlan;
                }
            }
        }

        throw new BusinessException("policyProductPlanId does not exist !");
    }

    @Override
    public List<PolicyPkgScheme> findPolicyPkgPlans(PolicyPkgScheme policyPkgPlan) {
        return this.policyRepository.findPolicyPkgPlans(policyPkgPlan);
    }

    @Override
    public List<PolicyProductPlan> findPolicyProductPlans(PolicyPkgScheme policyPkgPlan) {
        List<PolicyProductPlan> policyProductPlans = new ArrayList<PolicyProductPlan>();
        // get List<PolicyPkgPlan> by by PolicyPkgPlan.PolicyId and
        // PolicyPkgPlan.planCode
        List<PolicyPkgScheme> policyPkgPlans = this.findPolicyPkgPlans(policyPkgPlan);

        for (PolicyPkgScheme policyPkgPlan2 : policyPkgPlans) {
            List<PolicyPkgSchemeDetail> policyPkgPlanDetails = this.policyRepository
                    .findPolicyPkgPlanDetails(policyPkgPlan2.getPolicyPkgSchemeId());
            for (PolicyPkgSchemeDetail policyPkgPlanDetail : policyPkgPlanDetails) {
                PolicyProductPlan policyProductPlan = this.policyRepository
                        .findPolicyProductPlanById(policyPkgPlanDetail.getPolicyProductPlanId());
                policyProductPlans.add(policyProductPlan);
            }
        }
        return policyProductPlans;
    }

    @Override
    public PolicyYear findPolicyYear(Integer policyId, Date referDate) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("policyId", policyId);
        param.put("referDate", referDate);
        return policyRepository.findPolicyYear(param);
    }

    @Override
    public Policy findPolicyDetail(Policy policy) {
        // get policy by policyId or policyNo
        Policy returnPolicy = null;
        if (policy.getPolicyNo() != null) {
            returnPolicy = this.findPolicyByNo(policy.getPolicyNo());
        } else {
            if (policy.getPolicyId() != null) {
                returnPolicy = this.findPolicyById(policy.getPolicyId());
            }
        }

        // get policyId by policy
        int policyId = returnPolicy.getPolicyId();

        // get policyYear by policyId
        List<PolicyYear> policyYears = this.findPolicyYearsByPolicyId(policyId);
        returnPolicy.setPolicyYears(policyYears);

        // get policyAttachment by policyId
        PolicyAttachment policyAttachment = this.findPolicyAttachmentsByPolicyId(policyId);
        returnPolicy.setPolicyAttachment(policyAttachment);

        // get policypkgPlans
        List<PolicyPkgScheme> policyPkgPlans = this.findPolicyPkgPlansByPolicyId(policyId);

        // get policypkgPlanDetails
        for (int i = 0; i < policyPkgPlans.size(); i++) {
            PolicyPkgScheme policyPkgPlan = policyPkgPlans.get(i);
            List<PolicyPkgSchemeDetail> policyPkgPlanDetails = this
                    .findPolicyPkgPlanDetailsByPolicyPkgPlanId(policyPkgPlan.getPolicyPkgSchemeId());
            policyPkgPlan.setPolicyPkgSchemeDetails(policyPkgPlanDetails);
            policyPkgPlans.set(i, policyPkgPlan);
        }
        returnPolicy.setPolicyPkgSchemes(policyPkgPlans);

        // get policyProducts
        List<PolicyProduct> policyProducts = this.policyProductService
                .findPolicyProductsDetail(policy.getPolicyId());
        returnPolicy.setPolicyProducts(policyProducts);

        return returnPolicy;
    }

    @Override
    public List<PolicyYear> findPolicyYearsByPolicyId(Integer policyId) {
        return this.policyRepository.findPolicyYearsByPolicyId(policyId);
    }

    @Override
    public PolicyAttachment findPolicyAttachmentsByPolicyId(Integer policyId) {
        return this.policyRepository.findPolicyAttachmentsByPolicyId(policyId);
    }

    @Override
    public List<PolicyPkgSchemeDetail> findPolicyPkgPlanDetailsByPolicyPkgPlanId(Integer policyPkgPlanId) {
        return this.policyRepository.findPolicyPkgPlanDetails(policyPkgPlanId);
    }

    @Override
    public void setPolicyDefaultValue(Policy policy) { // NOSONAR
        if (policy != null) {
            List<PolicyProduct> a = policy.getPolicyProducts();
            if (a != null) {
                for (PolicyProduct b : a) {
                    if (isLifeProduct(b)) { // NOSONAR
                        // set default value for life product
                        b.setNelAge(999);
                        b.setNmlAge(999);
                        b.setNelAmt(new BigDecimal(999999999));
                        b.setNelAmt(new BigDecimal(999999999));
                    }
                    if (b.getStatus() == null) { // NOSONAR
                        b.setStatus("A");
                    }
                    //  set default collect office because it's required and
                    // may not input by UI // NOSONAR
                    b.setCollectOfficeId(1);
                    // set plan

                    List<PolicyProductPlan> plans = b.getPolicyProductPlans();
                    if (plans != null) { // NOSONAR
                        for (PolicyProductPlan policyProductPlan : plans) {
                            if (policyProductPlan.getStatus() == null) {
                                policyProductPlan.setStatus("A");
                            }
                            // benifit
                            List<PolicyProductBenefit> policyProductBenefits = policyProductPlan
                                    .getPolicyProductBenefits();
                            if (policyProductBenefits != null) {
                                for (PolicyProductBenefit policyProductBenefit : policyProductBenefits) {
                                    if (policyProductBenefit.getStatus() == null) {
                                        policyProductBenefit.setStatus("A");
                                    }
                                }
                            }
                        }

                    }
                    //  set default age for test when standard is null //
                    // NOSONAR
                    List<PolicyProductAge> ages = b.getPolicyProductAges();
                    if (ages != null) { // NOSONAR
                        for (PolicyProductAge age : ages) {
                            if (age != null) {
                                if (age.getMinAge() == null) {
                                    age.setMinAge(1);
                                }
                                if (age.getMaxEntryAge() == null) {
                                    age.setMaxEntryAge(20);
                                }
                                if (age.getMaxCoverAge() == null) {
                                    age.setMaxCoverAge(99);
                                }
                            }
                            if (age.getStatus() == null) {
                                age.setStatus("A");
                            }
                        }
                    }
                }
            }
            List<PolicyPkgScheme> policyPkgPlans = policy.getPolicyPkgSchemes();
            if (policyPkgPlans != null) {
                for (PolicyPkgScheme policyPkgPlan : policyPkgPlans) {
                    if (policyPkgPlan.getEffectiveDate() == null) { // NOSONAR
                        policyPkgPlan.setEffectiveDate(policy.getInitialEffectiveDate());
                    }
                    if (policyPkgPlan.getTransactionDate() == null) { // NOSONAR
                        policyPkgPlan.setTransactionDate(DateTimeUtil.getCurrentDateTime());
                    }
                    List<PolicyPkgSchemeDetail> policyPkgPlanDetails = policyPkgPlan.getPolicyPkgSchemeDetails();
                    if (policyPkgPlanDetails != null) { // NOSONAR
                        for (PolicyPkgSchemeDetail policyPkgPlanDetail : policyPkgPlanDetails) {
                            if (policyPkgPlanDetail.getEffectiveDate() == null) {
                                policyPkgPlanDetail.setEffectiveDate(policyPkgPlan.getEffectiveDate());
                            }
                            if (policyPkgPlanDetail.getTransactionDate() == null) {
                                policyPkgPlanDetail.setTransactionDate(DateTimeUtil.getCurrentDateTime());
                            }
                        }
                    }
                }
            }
        }
    }

    @Override
    public List<Policy> findPolicyByPolicyOwnerId(Integer policyOwnerId) {
        return this.policyRepository.findPolicyByPolicyOwnerId(policyOwnerId);

    }

    @Override
    public List<Policy> findPolicyByPolicyOwnerIds(List<Integer> policyOwnerIds) {
        List<Policy> policys = new ArrayList<Policy>();
        List<Policy> parampolicys = null; // NOSONAR
        for (Integer policyOwnerId : policyOwnerIds) {
            parampolicys = this.findPolicyByPolicyOwnerId(policyOwnerId);
            if (parampolicys != null) {
                policys.addAll(parampolicys);
            }
        }
        return policys;
    }

    @Override
    public void restCoverageCode(Integer policyId, Integer parentMembershipId) {
        // TblDependent?ParentMembershipId ? @parentMembershipId //
        // NOSONAR
        // List<Dependent> dependents = dependentRepository // NOSONAR
        // .findDependentByParentMembershipId(parentMembershipId); // NOSONAR
        //  DependentType // NOSONAR
        // TblMember ?MembershipId ? @parentMembershipId
        // 
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.aiatss.coast.pmm.application.service.agreement.PolicyService#
     * findPolicyByDayRange(java.util.Date, java.util.Date)
     */
    @Override
    public List<Policy> findPolicyByDayRange(Date rangeBeginDate, Date rangeEndDate) {
        return this.policyRepository.findPolicyByDayRange(rangeBeginDate, rangeEndDate);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.aiatss.coast.pmm.application.service.agreement.PolicyService#
     * findPackagePolicyByDayRange(java.util.Date, java.util.Date)
     */
    @Override
    public List<PolicyYear> findPackagePolicyByDayRange(Date rangeBeginDate, Date rangeEndDate) {
        return this.policyRepository.findPackagePolicyByDayRange(rangeBeginDate, rangeEndDate);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.aiatss.coast.pmm.application.service.agreement.PolicyService#
     * findNonPackagePolicyByDayRange(java.util.Date, java.util.Date)
     */
    @Override
    public List<PolicyYear> findNonPackagePolicyByDayRange(Date rangeBeginDate, Date rangeEndDate) {
        return this.policyRepository.findNonPackagePolicyByDayRange(rangeBeginDate, rangeEndDate);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.aiatss.coast.pmm.application.service.agreement.PolicyService#
     * findPolicyProductAge(java.lang.Integer, java.util.Date)
     */
    @Override
    public List<PolicyProductAge> findPolicyProductAge(Integer policyProductId, Date referDate) {
        return this.policyProductRepository.findPolicyProductAge(policyProductId, referDate);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.aiatss.coast.pmm.application.service.agreement.PolicyService#
     * findProductCodes(java.lang.Integer, java.util.Date)
     */
    @Override
    public List<String> findProductCodes(Integer policyId, Date referDate) {
        return this.policyProductRepository.findProductCodes(policyId, referDate);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.aiatss.coast.pmm.application.service.agreement.PolicyService#
     * findBenefitPlanCodes(java.lang.Integer, java.util.Date)
     */
    @Override
    public List<String> findBenefitPlanCodes(Integer policyId, Date referDate) {
        return this.policyProductRepository.findBenefitPlanCodes(policyId, referDate);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.aiatss.coast.pmm.application.service.agreement.PolicyService#
     * findPolicyProductForMinProductCode(java.lang.Integer, java.util.Date)
     */
    @Override
    public PolicyProduct findPolicyProductForMinProductCode(Integer policyId, Date referDate) {
        return this.policyRepository.findPolicyProductForMinProductCode(policyId, referDate);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.aiatss.coast.pmm.application.service.agreement.PolicyService#
     * isPackageProduct(java.lang.Integer)
     */
    @Override
    public boolean isPackageProduct(Integer policyId) {
        return true;
        // TODO Auto-generated method stub

    }

    /*
     * (non-Javadoc)
     * 
     * @see com.aiatss.coast.pmm.application.service.agreement.PolicyService#
     * findMaxBillToDate(java.lang.Integer)
     */
    @Override
    public Date findMaxBillToDate(Integer policyId) {
        return this.policyRepository.findMaxBillToDate(policyId);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.aiatss.coast.pmm.application.service.agreement.PolicyService#
     * findCommissionCode(java.lang.Integer)
     */
    @Override
    public List<String> findCommissionCodes(Integer policyId) {
        return this.policyRepository.findCommissionCodes(policyId);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.aiatss.coast.pmm.application.service.agreement.PolicyService#
     * findProducerCode(java.lang.Integer)
     */
    @Override
    public List<String> findProducerCodes(Integer policyId) {
        return this.policyRepository.findProducerCodes(policyId);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.aiatss.coast.pmm.application.service.agreement.PolicyService#
     * findProducerName(java.lang.Integer)
     */
    @Override
    public List<String> findProducerNames(Integer policyId) {
        return this.policyRepository.findProducerNames(policyId);
    }

}