<commit_before>/*
 * Copyright 2009 The Kuali Foundation.
 * 
 * Licensed under the Educational Community License, Version 1.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.opensource.org/licenses/ecl1.php
 * 
 * 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.kuali.kfs.module.cam.service.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.kuali.kfs.module.cab.CabConstants;
import org.kuali.kfs.module.cab.CabPropertyConstants;
import org.kuali.kfs.module.cam.CamsKeyConstants;
import org.kuali.kfs.module.cam.CamsConstants.DocumentTypeName;
import org.kuali.kfs.module.cam.businessobject.AssetLock;
import org.kuali.kfs.module.cam.dataaccess.CapitalAssetLockDao;
import org.kuali.kfs.module.cam.service.AssetLockService;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.rice.kns.service.BusinessObjectService;
import org.kuali.rice.kns.service.KualiConfigurationService;
import org.kuali.rice.kns.util.GlobalVariables;
import org.kuali.rice.kns.util.KNSConstants;
import org.kuali.rice.kns.util.RiceKeyConstants;
import org.kuali.rice.kns.util.UrlFactory;
import org.springframework.transaction.annotation.Transactional;

@Transactional
public class AssetLockServiceImpl implements AssetLockService {
    private static Logger LOG = Logger.getLogger(AssetLockService.class);

    private CapitalAssetLockDao capitalAssetLockDao;

    // FP document types includes:
    // CashReceipt,DistributionOfIncomeAndExpense,GeneralErrorCorrection,InternalBilling,ServiceBilling,YearEndDistributionOfIncomeAndExpense,YearEndGeneralErrorCorrection,ProcurementCard
    private static final Map<String, String> FINANCIAL_DOC_TYPE_MAP = new HashMap<String, String>();
    static {
        FINANCIAL_DOC_TYPE_MAP.put(KFSConstants.FinancialDocumentTypeCodes.CASH_RECEIPT,KFSConstants.FinancialDocumentTypeCodes.CASH_RECEIPT );
        FINANCIAL_DOC_TYPE_MAP.put(KFSConstants.FinancialDocumentTypeCodes.DISTRIBUTION_OF_INCOME_AND_EXPENSE, KFSConstants.FinancialDocumentTypeCodes.DISTRIBUTION_OF_INCOME_AND_EXPENSE);
        FINANCIAL_DOC_TYPE_MAP.put(KFSConstants.FinancialDocumentTypeCodes.GENERAL_ERROR_CORRECTION, KFSConstants.FinancialDocumentTypeCodes.GENERAL_ERROR_CORRECTION);
        FINANCIAL_DOC_TYPE_MAP.put(KFSConstants.FinancialDocumentTypeCodes.INTERNAL_BILLING, KFSConstants.FinancialDocumentTypeCodes.INTERNAL_BILLING);
        FINANCIAL_DOC_TYPE_MAP.put(KFSConstants.FinancialDocumentTypeCodes.SERVICE_BILLING, KFSConstants.FinancialDocumentTypeCodes.SERVICE_BILLING);
        FINANCIAL_DOC_TYPE_MAP.put(KFSConstants.FinancialDocumentTypeCodes.YEAR_END_DISTRIBUTION_OF_INCOME_AND_EXPENSE, KFSConstants.FinancialDocumentTypeCodes.YEAR_END_DISTRIBUTION_OF_INCOME_AND_EXPENSE);
        FINANCIAL_DOC_TYPE_MAP.put(KFSConstants.FinancialDocumentTypeCodes.YEAR_END_GENERAL_ERROR_CORRECTION, KFSConstants.FinancialDocumentTypeCodes.YEAR_END_GENERAL_ERROR_CORRECTION);
        FINANCIAL_DOC_TYPE_MAP.put(KFSConstants.FinancialDocumentTypeCodes.PROCUREMENT_CARD, KFSConstants.FinancialDocumentTypeCodes.PROCUREMENT_CARD);
    }

    // CAMS document types for maintain asset: AssetMaintenance, AssetFabrication, Asset Global, Asset Location Global,
    // LoanAndReturn
    private static final Map<String, String> ASSET_MAINTAIN_DOC_TYPE_MAP = new HashMap<String, String>();
    static {
        ASSET_MAINTAIN_DOC_TYPE_MAP.put(DocumentTypeName.ASSET_EDIT, DocumentTypeName.ASSET_EDIT);
        ASSET_MAINTAIN_DOC_TYPE_MAP.put(DocumentTypeName.ASSET_LOCATION_GLOBAL, DocumentTypeName.ASSET_LOCATION_GLOBAL);
        ASSET_MAINTAIN_DOC_TYPE_MAP.put(DocumentTypeName.ASSET_EQUIPMENT_LOAN_OR_RETURN, DocumentTypeName.ASSET_EQUIPMENT_LOAN_OR_RETURN);
        ASSET_MAINTAIN_DOC_TYPE_MAP.put(DocumentTypeName.ASSET_BARCODE_INVENTORY_ERROR, DocumentTypeName.ASSET_BARCODE_INVENTORY_ERROR);
        ASSET_MAINTAIN_DOC_TYPE_MAP.put(DocumentTypeName.ASSET_PAYMENT_FROM_CAB, DocumentTypeName.ASSET_PAYMENT_FROM_CAB);
    }

    // CAMS document types relating payment changes: AssetRetirement and Merge, AssetTransfer, AssetPayment, Asset Separate
    private static final Map<String, String> ASSET_PMT_CHG_DOC_TYPE_MAP = new HashMap<String, String>();
    static {
        ASSET_PMT_CHG_DOC_TYPE_MAP.put(DocumentTypeName.ASSET_RETIREMENT_GLOBAL, DocumentTypeName.ASSET_RETIREMENT_GLOBAL);
        ASSET_PMT_CHG_DOC_TYPE_MAP.put(DocumentTypeName.ASSET_TRANSFER, DocumentTypeName.ASSET_TRANSFER);
        ASSET_PMT_CHG_DOC_TYPE_MAP.put(DocumentTypeName.ASSET_PAYMENT, DocumentTypeName.ASSET_PAYMENT);
        ASSET_PMT_CHG_DOC_TYPE_MAP.put(DocumentTypeName.ASSET_SEPARATE, DocumentTypeName.ASSET_SEPARATE);
    }

    protected boolean isPurApDocument(String documentTypeName) {
        return CabConstants.PREQ.equals(documentTypeName) || CabConstants.CM.equals(documentTypeName);
    }

    /**
     * Gets the capitalAssetLockDao attribute.
     * 
     * @return Returns the capitalAssetLockDao.
     */
    public CapitalAssetLockDao getCapitalAssetLockDao() {
        return capitalAssetLockDao;
    }


    /**
     * Sets the capitalAssetLockDao attribute value.
     * 
     * @param capitalAssetLockDao The capitalAssetLockDao to set.
     */
    public void setCapitalAssetLockDao(CapitalAssetLockDao capitalAssetLockDao) {
        this.capitalAssetLockDao = capitalAssetLockDao;
    }


    /**
     * @param assetLocks must be from the same documentNumber and have the same documentTypeName
     * @return Return false without any of the asset being locked. Return true when all assets can be locked.
     * @see org.kuali.kfs.integration.cab.CapitalAssetBuilderModuleService#checkAndLockForDocument(java.util.Collection)
     */
    public synchronized boolean checkAndSetAssetLocks(List<AssetLock> assetLocks) {
        if (assetLocks == null || assetLocks.isEmpty() || !assetLocks.iterator().hasNext()) {
            return true;
        }

        AssetLock lock = assetLocks.iterator().next();
        String documentTypeName = lock.getDocumentTypeName();
        String documentNumber = lock.getDocumentNumber();

        // build asset number collection for lock checking.
        List assetNumbers = new ArrayList<Long>();
        for (AssetLock assetLock : assetLocks) {
            assetNumbers.add(assetLock.getCapitalAssetNumber());
        }

        // check each assetNumber is not locked by other document(s). PurAp document will ignore the locks since CAB batch will
        // set the lock anyway.
        if (isAssetLocked(assetNumbers, documentTypeName, documentNumber)) {
            return false;
        }
        // locking. here we got to delete and save again...it looks clumsy but it is constrained by the framework, see
        // MaintenanceDocumentBase.postProcessSave() for example.
        deleteAssetLocks(documentNumber, lock.getLockingInformation());
        getBusinessObjectService().save(assetLocks);

        return true;
    }

    /**
     * To get blocking document types for given document type. If given document type is FP, blocking documents will be CAMS payment
     * change documents. If given document type is CAMs maintain related, the blocking documents are all CAMs doc excluding FP and
     * PURAP. For other cases, returning null which will block all other documents.
     * 
     * @param documentTypeName
     * @return
     */
    protected Collection getBlockingDocumentTypes(String documentTypeName) {
        // FP document should be blocked by CAMS Payment change documents.
        if (FINANCIAL_DOC_TYPE_MAP.containsKey(documentTypeName)) {
            return ASSET_PMT_CHG_DOC_TYPE_MAP.values();
        }
        // CAMS maintain docs
        else if (ASSET_MAINTAIN_DOC_TYPE_MAP.containsKey(documentTypeName)) {
            List financialDocTypes = new ArrayList<String>();
            financialDocTypes.addAll(ASSET_MAINTAIN_DOC_TYPE_MAP.values());
            financialDocTypes.addAll(ASSET_PMT_CHG_DOC_TYPE_MAP.values());
            return financialDocTypes;
        }
        // For CAMs payment change document, any doc type can be the blocker, return null for this case
        return null;
    }

    /**
     * @see org.kuali.kfs.integration.cab.CapitalAssetBuilderModuleService#deleteLocks(java.lang.String, java.lang.String)
     */
    public void deleteAssetLocks(String documentNumber, String lockingInformation) {
        Map<String, Object> fieldValues = new HashMap<String, Object>();
        fieldValues.put(CabPropertyConstants.CapitalAssetLock.DOCUMENT_NUMBER, documentNumber);
        if (StringUtils.isNotBlank(lockingInformation)) {
            fieldValues.put(CabPropertyConstants.CapitalAssetLock.LOCKING_INFORMATION, lockingInformation);
        }
        getBusinessObjectService().deleteMatching(AssetLock.class, fieldValues);
    }

    /**
     * @see org.kuali.kfs.integration.cab.CapitalAssetBuilderModuleService#generateAssetLocks(java.util.Collection,
     *      java.lang.String, java.lang.String, java.lang.String)
     */
    public List<AssetLock> buildAssetLockHelper(List<Long> assetNumbers, String documentNumber, String documentType, String lockingInformation) {
        List<AssetLock> assetLocks = new ArrayList<AssetLock>();

        for (Long assetNumber : assetNumbers) {
            AssetLock newLock = new AssetLock(documentNumber, assetNumber, lockingInformation, documentType);
            assetLocks.add(newLock);
        }
        return assetLocks;
    }
<commit_msg>KULCAP-1147 Asset Edit - Review Related Documents tab<commit_after>/*
 * Copyright 2009 The Kuali Foundation.
 * 
 * Licensed under the Educational Community License, Version 1.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.opensource.org/licenses/ecl1.php
 * 
 * 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.kuali.kfs.module.cam.service.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.kuali.kfs.module.cab.CabConstants;
import org.kuali.kfs.module.cab.CabPropertyConstants;
import org.kuali.kfs.module.cam.CamsConstants;
import org.kuali.kfs.module.cam.CamsKeyConstants;
import org.kuali.kfs.module.cam.CamsConstants.DocumentTypeName;
import org.kuali.kfs.module.cam.businessobject.AssetLock;
import org.kuali.kfs.module.cam.dataaccess.CapitalAssetLockDao;
import org.kuali.kfs.module.cam.service.AssetLockService;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.rice.kns.service.BusinessObjectService;
import org.kuali.rice.kns.service.KualiConfigurationService;
import org.kuali.rice.kns.util.GlobalVariables;
import org.kuali.rice.kns.util.KNSConstants;
import org.kuali.rice.kns.util.RiceKeyConstants;
import org.kuali.rice.kns.util.UrlFactory;
import org.springframework.transaction.annotation.Transactional;

@Transactional
public class AssetLockServiceImpl implements AssetLockService {
    private static Logger LOG = Logger.getLogger(AssetLockService.class);

    private CapitalAssetLockDao capitalAssetLockDao;

    // FP document types includes:
    // CashReceipt,DistributionOfIncomeAndExpense,GeneralErrorCorrection,InternalBilling,ServiceBilling,YearEndDistributionOfIncomeAndExpense,YearEndGeneralErrorCorrection,ProcurementCard
    private static final Map<String, String> FINANCIAL_DOC_TYPE_MAP = new HashMap<String, String>();
    static {
        FINANCIAL_DOC_TYPE_MAP.put(KFSConstants.FinancialDocumentTypeCodes.CASH_RECEIPT,KFSConstants.FinancialDocumentTypeCodes.CASH_RECEIPT );
        FINANCIAL_DOC_TYPE_MAP.put(KFSConstants.FinancialDocumentTypeCodes.DISTRIBUTION_OF_INCOME_AND_EXPENSE, KFSConstants.FinancialDocumentTypeCodes.DISTRIBUTION_OF_INCOME_AND_EXPENSE);
        FINANCIAL_DOC_TYPE_MAP.put(KFSConstants.FinancialDocumentTypeCodes.GENERAL_ERROR_CORRECTION, KFSConstants.FinancialDocumentTypeCodes.GENERAL_ERROR_CORRECTION);
        FINANCIAL_DOC_TYPE_MAP.put(KFSConstants.FinancialDocumentTypeCodes.INTERNAL_BILLING, KFSConstants.FinancialDocumentTypeCodes.INTERNAL_BILLING);
        FINANCIAL_DOC_TYPE_MAP.put(KFSConstants.FinancialDocumentTypeCodes.SERVICE_BILLING, KFSConstants.FinancialDocumentTypeCodes.SERVICE_BILLING);
        FINANCIAL_DOC_TYPE_MAP.put(KFSConstants.FinancialDocumentTypeCodes.YEAR_END_DISTRIBUTION_OF_INCOME_AND_EXPENSE, KFSConstants.FinancialDocumentTypeCodes.YEAR_END_DISTRIBUTION_OF_INCOME_AND_EXPENSE);
        FINANCIAL_DOC_TYPE_MAP.put(KFSConstants.FinancialDocumentTypeCodes.YEAR_END_GENERAL_ERROR_CORRECTION, KFSConstants.FinancialDocumentTypeCodes.YEAR_END_GENERAL_ERROR_CORRECTION);
        FINANCIAL_DOC_TYPE_MAP.put(KFSConstants.FinancialDocumentTypeCodes.PROCUREMENT_CARD, KFSConstants.FinancialDocumentTypeCodes.PROCUREMENT_CARD);
    }

    // CAMS document types for maintain asset: AssetMaintenance, AssetFabrication, Asset Global, Asset Location Global,
    // LoanAndReturn
    private static final Map<String, String> ASSET_MAINTAIN_DOC_TYPE_MAP = new HashMap<String, String>();
    static {
        ASSET_MAINTAIN_DOC_TYPE_MAP.put(DocumentTypeName.ASSET_EDIT, DocumentTypeName.ASSET_EDIT);
        ASSET_MAINTAIN_DOC_TYPE_MAP.put(DocumentTypeName.ASSET_LOCATION_GLOBAL, DocumentTypeName.ASSET_LOCATION_GLOBAL);
        ASSET_MAINTAIN_DOC_TYPE_MAP.put(DocumentTypeName.ASSET_EQUIPMENT_LOAN_OR_RETURN, DocumentTypeName.ASSET_EQUIPMENT_LOAN_OR_RETURN);
        ASSET_MAINTAIN_DOC_TYPE_MAP.put(DocumentTypeName.ASSET_BARCODE_INVENTORY_ERROR, DocumentTypeName.ASSET_BARCODE_INVENTORY_ERROR);
        ASSET_MAINTAIN_DOC_TYPE_MAP.put(DocumentTypeName.ASSET_PAYMENT_FROM_CAB, DocumentTypeName.ASSET_PAYMENT_FROM_CAB);
    }

    // CAMS document types relating payment changes: AssetRetirement and Merge, AssetTransfer, AssetPayment, Asset Separate
    private static final Map<String, String> ASSET_PMT_CHG_DOC_TYPE_MAP = new HashMap<String, String>();
    static {
        ASSET_PMT_CHG_DOC_TYPE_MAP.put(DocumentTypeName.ASSET_RETIREMENT_GLOBAL, DocumentTypeName.ASSET_RETIREMENT_GLOBAL);
        ASSET_PMT_CHG_DOC_TYPE_MAP.put(DocumentTypeName.ASSET_TRANSFER, DocumentTypeName.ASSET_TRANSFER);
        ASSET_PMT_CHG_DOC_TYPE_MAP.put(DocumentTypeName.ASSET_PAYMENT, DocumentTypeName.ASSET_PAYMENT);
        ASSET_PMT_CHG_DOC_TYPE_MAP.put(DocumentTypeName.ASSET_SEPARATE, DocumentTypeName.ASSET_SEPARATE);
    }

    protected boolean isPurApDocument(String documentTypeName) {
        return CabConstants.PREQ.equals(documentTypeName) || CabConstants.CM.equals(documentTypeName);
    }

    /**
     * Gets the capitalAssetLockDao attribute.
     * 
     * @return Returns the capitalAssetLockDao.
     */
    public CapitalAssetLockDao getCapitalAssetLockDao() {
        return capitalAssetLockDao;
    }


    /**
     * Sets the capitalAssetLockDao attribute value.
     * 
     * @param capitalAssetLockDao The capitalAssetLockDao to set.
     */
    public void setCapitalAssetLockDao(CapitalAssetLockDao capitalAssetLockDao) {
        this.capitalAssetLockDao = capitalAssetLockDao;
    }


    /**
     * @param assetLocks must be from the same documentNumber and have the same documentTypeName
     * @return Return false without any of the asset being locked. Return true when all assets can be locked.
     * @see org.kuali.kfs.integration.cab.CapitalAssetBuilderModuleService#checkAndLockForDocument(java.util.Collection)
     */
    public synchronized boolean checkAndSetAssetLocks(List<AssetLock> assetLocks) {
        if (assetLocks == null || assetLocks.isEmpty() || !assetLocks.iterator().hasNext()) {
            return true;
        }

        AssetLock lock = assetLocks.iterator().next();
        String documentTypeName = lock.getDocumentTypeName();
        String documentNumber = lock.getDocumentNumber();

        // build asset number collection for lock checking.
        List assetNumbers = new ArrayList<Long>();
        for (AssetLock assetLock : assetLocks) {
            assetNumbers.add(assetLock.getCapitalAssetNumber());
        }

        // check each assetNumber is not locked by other document(s). PurAp document will ignore the locks since CAB batch will
        // set the lock anyway.
        if (isAssetLocked(assetNumbers, documentTypeName, documentNumber)) {
            return false;
        }
        // locking. here we got to delete and save again...it looks clumsy but it is constrained by the framework, see
        // MaintenanceDocumentBase.postProcessSave() for example.
        deleteAssetLocks(documentNumber, lock.getLockingInformation());
        getBusinessObjectService().save(assetLocks);

        return true;
    }

    /**
     * To get blocking document types for given document type. If given document type is FP, blocking documents will be CAMS payment
     * change documents. If given document type is CAMs maintain related, the blocking documents are all CAMs doc excluding FP and
     * PURAP. For other cases, returning null which will block all other documents.
     * 
     * @param documentTypeName
     * @return
     */
    protected Collection getBlockingDocumentTypes(String documentTypeName) {
        // FP document should be blocked by CAMS Payment change documents.
        if (FINANCIAL_DOC_TYPE_MAP.containsKey(documentTypeName)) {
            return ASSET_PMT_CHG_DOC_TYPE_MAP.values();
        }
        // CAMS maintain docs
        else if (ASSET_MAINTAIN_DOC_TYPE_MAP.containsKey(documentTypeName)) {
            List financialDocTypes = new ArrayList<String>();
            financialDocTypes.addAll(ASSET_MAINTAIN_DOC_TYPE_MAP.values());
            financialDocTypes.addAll(ASSET_PMT_CHG_DOC_TYPE_MAP.values());
            return financialDocTypes;
        }
        // FP blocking documents
        if (CamsConstants.DocumentTypeName.ASSET_FP_INQUIRY.equals(documentTypeName)){
            return FINANCIAL_DOC_TYPE_MAP.values();
        }

        // PREQ blocking documents
        if (CamsConstants.DocumentTypeName.ASSET_PREQ_INQUIRY.equals(documentTypeName)){
            List fpAndPurApDocTypes = new ArrayList<String>();
            fpAndPurApDocTypes.add(CabConstants.PREQ);
            fpAndPurApDocTypes.add(CabConstants.CM);
            return fpAndPurApDocTypes;
        }

        // For CAMs payment change document, any doc type can be the blocker, return null for this case
        return null;
    }

    /**
     * @see org.kuali.kfs.integration.cab.CapitalAssetBuilderModuleService#deleteLocks(java.lang.String, java.lang.String)
     */
    public void deleteAssetLocks(String documentNumber, String lockingInformation) {
        Map<String, Object> fieldValues = new HashMap<String, Object>();
        fieldValues.put(CabPropertyConstants.CapitalAssetLock.DOCUMENT_NUMBER, documentNumber);
        if (StringUtils.isNotBlank(lockingInformation)) {
            fieldValues.put(CabPropertyConstants.CapitalAssetLock.LOCKING_INFORMATION, lockingInformation);
        }
        getBusinessObjectService().deleteMatching(AssetLock.class, fieldValues);
    }

    /**
     * @see org.kuali.kfs.integration.cab.CapitalAssetBuilderModuleService#generateAssetLocks(java.util.Collection,
     *      java.lang.String, java.lang.String, java.lang.String)
     */
    public List<AssetLock> buildAssetLockHelper(List<Long> assetNumbers, String documentNumber, String documentType, String lockingInformation) {
        List<AssetLock> assetLocks = new ArrayList<AssetLock>();

        for (Long assetNumber : assetNumbers) {
            AssetLock newLock = new AssetLock(documentNumber, assetNumber, lockingInformation, documentType);
            assetLocks.add(newLock);
        }
        return assetLocks;
    }

{'fraction_non_alphanumeric': 0.07647656363372515, 'fraction_numerical': 0.0009674454602621777, 'mean_word_length': 4.280715197956577, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 34, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3524760', 'n_tokens_mistral': 6266, 'n_tokens_neox': 6024, 'n_words': 1168}