# ProductAttributeInfoManagerImpl.java

    package com.mycim.server.spec.manager.impl;

    import com.mycim.framework.utils.beans.BeanUtils;
    import com.mycim.framework.utils.lang.StringUtils;
    import com.mycim.framework.utils.lang.collections.CollectionUtils;
    import com.mycim.server.spec.dao.ProductAttributeInfoDao;
    import com.mycim.server.spec.manager.ProcessSpecInfoManager;
    import com.mycim.server.spec.manager.ProductAttributeInfoManager;
    import com.mycim.valueobject.bas.TransactionLog;
    import com.mycim.valueobject.consts.VersionStatus;
    import com.mycim.valueobject.prp.ProcessSpecInfo;
    import com.mycim.valueobject.prp.ProductAttributeInfo;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;

    /**
     * Product Attribute
     *
     * @author Qiansheng.Wang
     * @since 2021-05-15
     */
    @Service
    @Transactional
    public class ProductAttributeInfoManagerImpl implements ProductAttributeInfoManager {

        @Autowired
        ProductAttributeInfoDao productAttributeInfoDao;

        @Autowired
        ProcessSpecInfoManager processSpecInfoManager;

        @Override
        public void insertProductAttributeInfos(TransactionLog transactionLog,
                                                List<ProductAttributeInfo> productAttributeInfos) {

            for (ProductAttributeInfo productAttributeInfo : productAttributeInfos) {
                productAttributeInfo.setActiveFlag(false);
                productAttributeInfo.setActiveUser(null);
                productAttributeInfo.setActiveTime(null);
                productAttributeInfo.setCurrentStatus(VersionStatus.UNFROZEN_KEY);

                productAttributeInfo.setCreateUserId(transactionLog.getTransPerformedBy());
                productAttributeInfo.setCreateTime(transactionLog.getTransStartTimestamp());

                productAttributeInfo.setLastUpdatedUser(transactionLog.getTransPerformedBy());
                productAttributeInfo.setLastUpdatedTime(transactionLog.getTransStartTimestamp());
            }

            productAttributeInfoDao.insertProductAttributeInfos(productAttributeInfos);
        }

        @Override
        public void deleteProductAttributeInfos(List<ProductAttributeInfo> productAttributeInfos) {
            if (CollectionUtils.isEmpty(productAttributeInfos)) {
                return;
            }
            productAttributeInfoDao.deleteProductAttributeInfos(productAttributeInfos);
        }

        @Override
        public void updateStatusOfProductAttributeInfos(TransactionLog transactionLog,
                                                        List<ProductAttributeInfo> productAttributeInfos,
                                                        String targetStatus) {
            for (ProductAttributeInfo attributeInfo : productAttributeInfos) {

                if (StringUtils.equalsIgnoreCase(targetStatus, VersionStatus.ACTIVE_KEY)) {
                    attributeInfo.setActiveFlag(true);
                    attributeInfo.setActiveTime(transactionLog.getTransStartTimestamp());
                    attributeInfo.setActiveUser(transactionLog.getTransPerformedBy());
                }

                attributeInfo.setCurrentStatus(targetStatus);
                attributeInfo.setLastUpdatedTime(transactionLog.getTransStartTimestamp());
                attributeInfo.setLastUpdatedUser(transactionLog.getTransPerformedBy());
            }

            productAttributeInfoDao.updateStatusOfProductAttributeInfos(productAttributeInfos);
        }

        @Override
        public void saveProductAttributeInfos(TransactionLog transactionLog, ProcessSpecInfo processSpecInfo,
                                              List<ProductAttributeInfo> willSaveProductAttributeInfo) {
            List<ProductAttributeInfo> attributeInfoInDb = getProductAttributeInfosByProcess(
                    processSpecInfo.getProcessRrn(), processSpecInfo.getProcessVersion());

            List<ProductAttributeInfo> insertList = new ArrayList<>();
            List<ProductAttributeInfo> updateList = new ArrayList<>();

            for (ProductAttributeInfo attribute : willSaveProductAttributeInfo) {
                if (attributeInfoInDb.contains(attribute)) {
                    BeanUtils.copyProperties(attributeInfoInDb.get(attributeInfoInDb.indexOf(attribute)), attribute);

                    attribute.setCurrentStatus(VersionStatus.UNFROZEN_KEY);

                    attribute.setLastUpdatedUser(transactionLog.getTransPerformedBy());
                    attribute.setLastUpdatedTime(transactionLog.getTransStartTimestamp());

                    updateList.add(attribute);
                } else {
                    attribute.setActiveFlag(false);
                    attribute.setCurrentStatus(VersionStatus.UNFROZEN_KEY);
                    attribute.setLastUpdatedUser(transactionLog.getTransPerformedBy());
                    attribute.setLastUpdatedTime(transactionLog.getTransStartTimestamp());
                    attribute.setCreateUserId(transactionLog.getTransPerformedBy());
                    attribute.setCreateTime(transactionLog.getTransStartTimestamp());

                    insertList.add(attribute);
                }
            }

            productAttributeInfoDao.insertProductAttributeInfos(insertList);
            productAttributeInfoDao.updateStatusOfProductAttributeInfos(updateList);
        }

        @Override
        public ProductAttributeInfo getProductAttributeInfos(Long processRrn, Integer processVersion, Long productRrn,
                                                             Integer productVersion) {
            return productAttributeInfoDao
                    .getProductAttributeInfoByPrimaryKey(productRrn, productVersion, processRrn, processVersion);
        }

        @Override
        public List<ProductAttributeInfo> getProductAttributeInfos(Long productRrn, Long processRrn) {
            ProductAttributeInfo queryTemp = new ProductAttributeInfo();

            queryTemp.setProductRrn(productRrn);
            queryTemp.setProcessRrn(processRrn);

            return getProductAttributeInfos(queryTemp);
        }

        @Override
        public List<ProductAttributeInfo> getProductAttributeInfosByProduct(Long productRrn) {
            ProductAttributeInfo queryTemp = new ProductAttributeInfo();

            queryTemp.setProductRrn(productRrn);

            return getProductAttributeInfos(queryTemp);
        }

        @Override
        public List<ProductAttributeInfo> getProductAttributeInfosByProcess(Long processRrn, Integer processVersion) {
            ProductAttributeInfo queryTemp = new ProductAttributeInfo();

            queryTemp.setProcessRrn(processRrn);
            queryTemp.setProcessVersion(processVersion);

            return getProductAttributeInfos(queryTemp);
        }

        @Override
        public List<ProductAttributeInfo> getProductAttributeInfosByProcess(Long processRrn, Integer processVersion,
                                                                            Long productRrn) {
            ProductAttributeInfo queryTemp = new ProductAttributeInfo();

            queryTemp.setProcessRrn(processRrn);
            queryTemp.setProcessVersion(processVersion);
            queryTemp.setProductRrn(productRrn);

            return getProductAttributeInfos(queryTemp);
        }

        private List<ProductAttributeInfo> getProductAttributeInfos(ProductAttributeInfo attributeInfoQueryTemp) {
            List<ProductAttributeInfo> infos = productAttributeInfoDao
                    .getProductAttributeInfoWithPrimaryKey(attributeInfoQueryTemp);
            if (CollectionUtils.isEmpty(infos)) {
                infos = new ArrayList<>();
            }
            return infos;
        }

    }