jp.co.opentone.bsol.linkbinder.service.admin.impl.CompanyServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for jp.co.opentone.bsol.linkbinder.service.admin.impl.CompanyServiceImpl.java

Source

/*
 * Copyright 2016 OPEN TONE Inc.
 *
 * Licensed 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 jp.co.opentone.bsol.linkbinder.service.admin.impl;

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

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jp.co.opentone.bsol.framework.core.config.SystemConfig;
import jp.co.opentone.bsol.framework.core.dao.KeyDuplicateException;
import jp.co.opentone.bsol.framework.core.dao.RecordNotFoundException;
import jp.co.opentone.bsol.framework.core.dao.StaleRecordException;
import jp.co.opentone.bsol.framework.core.generator.GeneratorFailedException;
import jp.co.opentone.bsol.framework.core.generator.excel.WorkbookGenerator;
import jp.co.opentone.bsol.framework.core.service.ServiceAbortException;
import jp.co.opentone.bsol.framework.core.util.ArgumentValidator;
import jp.co.opentone.bsol.linkbinder.dao.CompanyDao;
import jp.co.opentone.bsol.linkbinder.dao.CompanyUserDao;
import jp.co.opentone.bsol.linkbinder.dao.ProjectCompanyDao;
import jp.co.opentone.bsol.linkbinder.dao.UserDao;
import jp.co.opentone.bsol.linkbinder.dto.Company;
import jp.co.opentone.bsol.linkbinder.dto.CompanyUser;
import jp.co.opentone.bsol.linkbinder.dto.ProjectCompany;
import jp.co.opentone.bsol.linkbinder.dto.ProjectUser;
import jp.co.opentone.bsol.linkbinder.dto.SearchCompanyResult;
import jp.co.opentone.bsol.linkbinder.dto.User;
import jp.co.opentone.bsol.linkbinder.dto.condition.SearchCompanyCondition;
import jp.co.opentone.bsol.linkbinder.dto.condition.SearchUserCondition;
import jp.co.opentone.bsol.linkbinder.message.ApplicationMessageCode;
import jp.co.opentone.bsol.linkbinder.service.AbstractService;
import jp.co.opentone.bsol.linkbinder.service.admin.CompanyService;

/**
 * ??????????.
 * @author opentone
 */
@Service
@Transactional(rollbackFor = { ServiceAbortException.class })
public class CompanyServiceImpl extends AbstractService implements CompanyService {

    /**
     * SerialVersionUID.
     */
    private static final long serialVersionUID = 2347882896607861272L;

    /**
     * .
     */
    private int dataCount;

    /**
     * ???EXCEL???KEY.
     */
    private static final String SHEET_KEY = "excel.sheetname.companyindex";

    /**
     * EXCEL?????????????.
     */
    private static final String SHEET_DEFAULT = "CompanyIndex";

    /**
     * Excel????(?).
     */
    private static final List<String> MASTER_HEADER;
    static {
        MASTER_HEADER = new ArrayList<String>();
        MASTER_HEADER.add("ID");
        MASTER_HEADER.add("");
        MASTER_HEADER.add("??");
    }

    /**
     * Excel???.
     */
    private static final List<String> MASTER_FIELDS;
    static {
        MASTER_FIELDS = new ArrayList<String>();
        MASTER_FIELDS.add("id");
        MASTER_FIELDS.add("companyCd");
        MASTER_FIELDS.add("name");
    }

    /**
     * Excel?????.
     */
    private static final List<String> PROJECT_HEADER;
    static {
        PROJECT_HEADER = new ArrayList<String>();
        PROJECT_HEADER.add("ID");
        PROJECT_HEADER.add("");
        PROJECT_HEADER.add("??");
        PROJECT_HEADER.add("");
    }

    /**
     * Excel???.
     */
    private static final List<String> PROJECT_FIELDS;
    static {
        PROJECT_FIELDS = new ArrayList<String>();
        PROJECT_FIELDS.add("projectCompanyId");
        PROJECT_FIELDS.add("companyCd");
        PROJECT_FIELDS.add("name");
        PROJECT_FIELDS.add("role");
    }

    /*
     * (non-Javadoc)
     * @see
     * jp.co.opentone.bsol.linkbinder.service.admin.CompanyService#search(jp.co.opentone.bsol.linkbinder
     * .dto.SearchCompanyCondition)
     */
    @Transactional(readOnly = true)
    public SearchCompanyResult search(SearchCompanyCondition condition) throws ServiceAbortException {
        ArgumentValidator.validateNotNull(condition);
        // ?
        List<Company> companyList = searchCompany(condition);
        SearchCompanyResult result = createResult(companyList);
        return result;
    }

    /* (non-Javadoc)
     * @see jp.co.opentone.bsol.linkbinder.service.admin.CompanyService#searchProjectCompany(java.lang.String)
     */
    public List<Company> searchRelatedToProject(String projectId) {
        ArgumentValidator.validateNotEmpty(projectId);

        SearchCompanyCondition condition = new SearchCompanyCondition();
        condition.setProjectId(projectId);

        return findCompany(condition);
    }

    /*
     * (non-Javadoc)
     * @see
     * jp.co.opentone.bsol.linkbinder.service.admin.CompanyService#searchNotProjectCompany()
     */
    @Transactional(readOnly = true)
    public List<Company> searchNotAssigned() {
        return findNotAssignTo(getCurrentProjectId());
    }

    /*
     * (non-Javadoc)
     * @see
     * jp.co.opentone.bsol.linkbinder.service.admin.CompanyService#assignTo(jp.co.opentone.bsol.linkbinder
     * .dto.Company)
     */
    public Long assignTo(Company company) throws ServiceAbortException {
        ArgumentValidator.validateNotNull(company);
        // ???
        validateAssignToProject(company);
        // ??
        return insertProjectCompany(company);
    }

    /*
     * (non-Javadoc)
     * @see
     * jp.co.opentone.bsol.linkbinder.service.admin.CompanyService#delete(jp.co.opentone.bsol.linkbinder
     * .dto.Company)
     */
    public void delete(Company company) throws ServiceAbortException {
        if (StringUtils.isEmpty(getCurrentProjectId())) {
            validateDeleteMaster(company);
            Company deleteCompany = createDeleteCompany(company);
            deleteCompany(deleteCompany);
        } else {
            validateDeleteProject(company);
            ProjectCompany deleteProjectCompany = createDeleteProjectCompany(company);
            deleteProjectCompany(deleteProjectCompany);
            Company exclusiveCompany = createExclusiveCheckCompany(company);
            // 
            updateCompany(exclusiveCompany);
        }
    }

    /*
     * (non-Javadoc)
     * @see jp.co.opentone.bsol.linkbinder.service.admin.CompanyService#find(java.lang.Long)
     */
    @Transactional(readOnly = true)
    public Company find(Long id) throws ServiceAbortException {
        ArgumentValidator.validateNotNull(id);
        Company company = null;
        if (StringUtils.isEmpty(getCurrentProjectId())) {
            company = findById(id);
        } else {
            // ??????
            company = findProjectCompanyById(id);
            validateProjectId(company.getProjectId());
        }
        return company;

    }

    /*
     * (non-Javadoc)
     * @see
     * jp.co.opentone.bsol.linkbinder.service.admin.CompanyService#findMembers(java.lang.Long)
     */
    @Transactional(readOnly = true)
    public List<CompanyUser> findMembers(Long id) throws ServiceAbortException {
        ArgumentValidator.validateNotNull(id);
        validatePermission();
        return findCompanyMembers(id);
    }

    /*
     * (non-Javadoc)
     * @see
     * jp.co.opentone.bsol.linkbinder.service.admin.CompanyService#generateExcel(java.util
     * .List)
     */
    @Transactional(readOnly = true)
    public byte[] generateExcel(List<Company> companies) throws ServiceAbortException {
        try {
            String sheetName = SystemConfig.getValue(SHEET_KEY);
            if (StringUtils.isEmpty(sheetName)) {
                sheetName = SHEET_DEFAULT;
            }
            WorkbookGenerator generator = new WorkbookGenerator(sheetName, companies, getOutputField(companies),
                    getHeaderNames(companies), true);
            return generator.generate();
        } catch (GeneratorFailedException e) {
            throw new ServiceAbortException(e.getMessage());
        }

    }

    /*
     * (non-Javadoc)
     * @see
     * jp.co.opentone.bsol.linkbinder.service.admin.CompanyService#save(jp.co.opentone.bsol.linkbinder.dto
     * .Company)
     */
    public Long save(Company company) throws ServiceAbortException {
        ArgumentValidator.validateNotNull(company);
        // Validate?
        validate(company);
        // ?
        if (StringUtils.isEmpty(getCurrentProjectId())) {
            if (!company.isNew()) {
                // 
                return updateCompany(createUpdateCompany(company));
            }
            // ?
            return insertCompany(createInsertCompany(company));
        } else {
            // ?
            Long id = updateProjectCompany(company);
            // 
            updateCompany(createExclusiveCheckCompany(company));

            return id;
        }
    }

    /*
     * (non-Javadoc)
     * @see
     * jp.co.opentone.bsol.linkbinder.service.admin.CompanyService#saveMembers(jp.co.opentone.bsol.linkbinder
     * .dto.Company, java.util.List)
     */
    public void saveMembers(Company company, List<User> users) throws ServiceAbortException {
        ArgumentValidator.validateNotNull(company);
        ArgumentValidator.validateNotNull(users);
        validatePermission();

        // ?????
        validateUserExists(users);
        // ?????????????
        validateProjectUserExists(company.getId(), users);
        // ?????
        deleteAllCompanyUsers(company.getProjectCompanyId());
        // ???
        insertCompanyUser(company, users);
        // 
        Company exclusiveCompany = createExclusiveCheckCompany(company);
        updateCompany(exclusiveCompany);
    }

    /*
     * (non-Javadoc)
     * @see
     * jp.co.opentone.bsol.linkbinder.service.admin.CompanyService#validate(jp.co.opentone.bsol.linkbinder
     * .dto.Company)
     */
    @Transactional(readOnly = true)
    public boolean validate(Company company) throws ServiceAbortException {
        // ?
        if (StringUtils.isEmpty(getCurrentProjectId())) {
            validateMaster(company);
        } else {
            validateProjectMaster(company);
        }
        return true;
    }

    /**
     * ???????.
     * @param condition 
     * @return 
     */
    private List<Company> findCompany(SearchCompanyCondition condition) {
        CompanyDao dao = getDao(CompanyDao.class);
        return dao.find(condition);
    }

    /**
     * ?.
     * @param condition ?
     * @throws ServiceAbortException
     */
    private List<Company> searchCompany(SearchCompanyCondition condition) throws ServiceAbortException {
        // SystemAdminHome
        if (StringUtils.isEmpty(getCurrentProjectId())) {
            validateNotSystemAdmin();
        } else {
            if (!isSystemAdmin(getCurrentUser())) {
                // ???????????????
                validateProjectUserDiff();
            }
        }

        // 0???
        validateExistCompany(condition);
        List<Company> company = findCompany(condition);
        // ????????????????
        validatePageSpecificationExistCompany(company);
        return company;
    }

    /**
     * ??????????????.
     * @throws ServiceAbortException ??????
     */
    private void validateProjectUserDiff() throws ServiceAbortException {
        if (findProjectUser(getCurrentProjectId(), getCurrentUser().getEmpNo()) == null) {
            throw new ServiceAbortException(ApplicationMessageCode.CANNOT_PERFORM_BECAUSE_PROJECT_DIFF);
        }
    }

    /**
     * ??[2] SystemAdmin,ProjectAdmin??.
     * @return boolean SystemAdmin??ProjectAdmin???true /
     *         SystemAdmin??ProjectAdmin?false
     */
    private boolean isValidPermission(String projectId) {
        return isSystemAdmin(getCurrentUser()) || isProjectAdmin(getCurrentUser(), projectId);
    }

    /**
     * ??????.
     * @throws ServiceAbortException ????
     */
    private void validatePermission() throws ServiceAbortException {
        if (!isValidPermission(getCurrentProjectId())) {
            throw new ServiceAbortException(
                    ApplicationMessageCode.CANNOT_PERFORM_BECAUSE_ACCESS_LEVEL_INSUFFICIENT);
        }
    }

    /**
     * ??.
     * @param condition ?
     * @return int 
     */
    private int countCompany(SearchCompanyCondition condition) {
        CompanyDao dao = getDao(CompanyDao.class);
        return dao.countCompany(condition);
    }

    /**
     * ????.
     * @param condition ?
     * @return ?0???false / ?0??????true
     */
    private boolean isExistCompany(SearchCompanyCondition condition) {
        dataCount = countCompany(condition);
        return dataCount > 0;
    }

    /**
     * ??????.
     * @param condition ?
     * @throws ServiceAbortException ????
     */
    private void validateExistCompany(SearchCompanyCondition condition) throws ServiceAbortException {
        if (!isExistCompany(condition)) {
            throw new ServiceAbortException(ApplicationMessageCode.NO_DATA_FOUND);
        }

    }

    /**
     * ????????.
     * @param company 
     * @return ??????false / ???true
     */
    private boolean isPageSpecificationExistCompany(List<Company> company) {
        return company.size() > 0;
    }

    /**
     * ??????????.
     * @param companies 
     * @throws ServiceAbortException ????
     */
    private void validatePageSpecificationExistCompany(List<Company> companies) throws ServiceAbortException {
        // ????????????????
        if (!isPageSpecificationExistCompany(companies)) {
            throw new ServiceAbortException(ApplicationMessageCode.NO_PAGE_FOUND);
        }
    }

    /**
     * ?????.
     * @param companyList 
     * @return 
     */
    private SearchCompanyResult createResult(List<Company> companyList) {
        SearchCompanyResult result = new SearchCompanyResult();
        result.setCompanyList(companyList);
        result.setCount(dataCount);
        return result;
    }

    /**
     * ????.
     * @return 
     */
    private List<String> getOutputField(List<Company> companies) {
        // ?
        if (StringUtils.isNotEmpty(getCurrentProjectId())) {
            return PROJECT_FIELDS;
        }
        return MASTER_FIELDS;
    }

    /**
     * ??????.
     * @return ??
     */
    private List<String> getHeaderNames(List<Company> companies) {
        if (StringUtils.isNotEmpty(getCurrentProjectId())) {
            return PROJECT_HEADER;
        }
        return MASTER_HEADER;
    }

    /**
     * Project????.
     * @param ProjectId ID
     * @return 
     */
    private List<Company> findNotAssignTo(String projectId) {
        if (StringUtils.isNotEmpty(projectId)) {
            CompanyDao dao = getDao(CompanyDao.class);
            return dao.findNotAssignTo(projectId);
        }
        return new ArrayList<Company>(); // NULL?????
    }

    /**
     * ??.
     * @param company 
     * @return ID
     * @throws ServiceAbortException
     */
    private Long insertProjectCompany(Company company) throws ServiceAbortException {
        ProjectCompany projectCompany = new ProjectCompany();
        projectCompany.setProjectId(getCurrentProjectId());
        projectCompany.setCompanyId(company.getId());
        User loginUser = getCurrentUser();
        projectCompany.setCreatedBy(loginUser);
        projectCompany.setUpdatedBy(loginUser);
        try {
            ProjectCompanyDao dao = getDao(ProjectCompanyDao.class);
            return dao.create(projectCompany);
        } catch (KeyDuplicateException kde) {
            throw new ServiceAbortException(kde);
        }
    }

    /**
     * ????.
     * @param company 
     * @throws ServiceAbortException
     */
    private void validateAssignToProject(Company company) throws ServiceAbortException {
        // ???2?
        validatePermission();
        // ???????
        findById(company.getId());
        // ???????????
        validateAlreadyCompanyProject(company);
    }

    /**
     * ?.
     * @param company 
     * @return ??ID
     * @throws ServiceAbortException
     */
    private Long insertCompany(Company company) throws ServiceAbortException {
        CompanyDao dao = getDao(CompanyDao.class);
        try {
            return dao.create(company);
        } catch (KeyDuplicateException kde) {
            throw new ServiceAbortException(kde);
        }
    }

    /**
     * ???. ?????.
     * @param company 
     * @return 
     */
    private Company createInsertCompany(Company company) {
        User loginUser = getCurrentUser();
        Company insertCompany = new Company();
        insertCompany.setCompanyCd(company.getCompanyCd());
        insertCompany.setName(company.getName());
        insertCompany.setCreatedBy(loginUser);
        insertCompany.setUpdatedBy(loginUser);
        return insertCompany;
    }

    /**
     * ??Validate??.
     * @param company 
     * @throws ServiceAbortException ????????
     */
    private void validateMaster(Company company) throws ServiceAbortException {
        // ????
        if (company.isNew()) {
            // SystemADmin?
            validateNotSystemAdmin();
        } else {
            // ???
            // ?0???
            findById(company.getId());
        }
        // ????company_cd??????
        validateExistCompanyCode(company);
    }

    /**
     * ??Validate??.
     * @param company 
     * @throws ServiceAbortException ????????
     */
    private void validateProjectMaster(Company company) throws ServiceAbortException {
        // SystemAdmin,ProjectAdmin?
        validatePermission();
        // ?0???
        findProjectCompanyById(company.getId());
        // ??????
        validateProjectId(company.getProjectId());
    }

    /**
     * ?.(company).
     * @param company 
     * @return ID
     * @throws ServiceAbortException
     */
    private Long updateCompany(Company company) throws ServiceAbortException {
        CompanyDao dao = getDao(CompanyDao.class);
        try {
            dao.update(company);
        } catch (KeyDuplicateException kdle) {
            throw new ServiceAbortException(kdle);
        } catch (StaleRecordException sre) {
            throw new ServiceAbortException(ApplicationMessageCode.CANNOT_PERFORM_BECAUSE_COMPANY_ALREADY_UPDATED);
        }
        return company.getId();
    }

    /**
     * ?.(project_company).
     * @param projectCompany 
     * @return ??ID
     * @throws ServiceAbortException 
     */
    private Long updateProjectCompany(Company company) throws ServiceAbortException {
        ProjectCompanyDao dao = getDao(ProjectCompanyDao.class);
        try {
            ProjectCompany updateProjectCompany = createUpdateProjectCompany(company);
            dao.update(updateProjectCompany);
        } catch (KeyDuplicateException kdle) {
            throw new ServiceAbortException(kdle);
        } catch (StaleRecordException sre) {
            throw new ServiceAbortException(ApplicationMessageCode.CANNOT_PERFORM_BECAUSE_COMPANY_ALREADY_UPDATED);
        }
        return company.getId();
    }

    /**
     * ???.
     * @param company 
     * @return 
     */
    private Company createUpdateCompany(Company company) {
        Company updateCompany = new Company();
        updateCompany.setId(company.getId());
        updateCompany.setCompanyCd(company.getCompanyCd());
        updateCompany.setName(company.getName());
        updateCompany.setUpdatedBy(getCurrentUser());
        updateCompany.setVersionNo(company.getVersionNo());
        return updateCompany;
    }

    /**
     * ???.
     * @param company 
     * @return (ProjectCompany)
     * @throws ServiceAbortException
     */
    private ProjectCompany createUpdateProjectCompany(Company company) throws ServiceAbortException {
        ProjectCompany updateProjectCompany = new ProjectCompany();
        updateProjectCompany.setId(company.getProjectCompanyId());
        updateProjectCompany.setRole(company.getRole());
        updateProjectCompany.setUpdatedBy(getCurrentUser());
        return updateProjectCompany;
    }

    /**
     * ID????.
     * @param id ID
     * @return ???
     * @throws ServiceAbortException ???????
     */
    private Company findById(Long id) throws ServiceAbortException {
        ArgumentValidator.validateNotNull(id);
        try {
            CompanyDao dao = getDao(CompanyDao.class);
            return dao.findById(id);
        } catch (RecordNotFoundException rnfe) {
            throw new ServiceAbortException(ApplicationMessageCode.NO_DATA_FOUND);
        }
    }

    /**
     * ID????.
     * @param company 
     * @return ???
     * @throws ServiceAbortException ???????
     */
    private Company findProjectCompanyById(Long id) throws ServiceAbortException {
        ArgumentValidator.validateNotNull(id);
        try {
            CompanyDao dao = getDao(CompanyDao.class);
            return dao.findProjectCompanyById(id, getCurrentProjectId());
        } catch (RecordNotFoundException rnfe) {
            throw new ServiceAbortException(ApplicationMessageCode.NO_DATA_FOUND);
        }
    }

    /**
     * ??????.
     * @param id ID
     * @return ????
     * @throws ServiceAbortException
     */
    private List<CompanyUser> findCompanyMembers(Long id) {
        CompanyDao dao = getDao(CompanyDao.class);
        List<CompanyUser> listCompanyUser = dao.findMembers(id);
        return listCompanyUser;
    }

    /**
     * ?????????????.
     * @param id ID
     * @param users 
     * @throws ServiceAbortException ??????
     */
    private void validateProjectUserExists(Long id, List<User> users) throws ServiceAbortException {
        SearchUserCondition condition = new SearchUserCondition();
        condition.setProjectId(getCurrentProjectId());

        UserDao dao = getDao(UserDao.class);
        List<ProjectUser> projectUsers = dao.findProjectUser(condition);

        for (final User u : users) {
            //  ????????
            Object ret = CollectionUtils.find(projectUsers, new Predicate() {
                public boolean evaluate(Object object) {
                    ProjectUser pu = (ProjectUser) object;
                    return u.getEmpNo().equals(pu.getUser().getEmpNo());
                }
            });

            if (ret == null) {
                throw new ServiceAbortException("invalid user",
                        ApplicationMessageCode.CANNOT_PERFORM_BECAUSE_USER_ALREADY_DELETED, u.getLabel());
            }
        }
    }

    /**
     * ????.
     * @param id ID
     * @return ??
     * @throws ServiceAbortException
     */
    private Integer deleteAllCompanyUsers(Long id) throws ServiceAbortException {
        try {
            CompanyUserDao dao = getDao(CompanyUserDao.class);
            CompanyUser companyUser = new CompanyUser();
            companyUser.setProjectCompanyId(id);
            companyUser.setUpdatedBy(getCurrentUser());
            return dao.deleteByCompanyId(companyUser);
        } catch (KeyDuplicateException kdle) {
            throw new ServiceAbortException(kdle);
        } catch (StaleRecordException sre) {
            throw new ServiceAbortException(ApplicationMessageCode.CANNOT_PERFORM_BECAUSE_COMPANY_ALREADY_UPDATED);
        }
    }

    /**
     * ?.
     * @param companyUser 
     * @throws ServiceAbortException
     */
    private void insertCompanyUser(Company company, List<User> listUser) throws ServiceAbortException {
        try {
            CompanyUserDao dao = getDao(CompanyUserDao.class);
            CompanyUser companyUser = null;
            for (User user : listUser) {
                companyUser = createCompanyUser(company, user);
                dao.create(companyUser);
            }
        } catch (KeyDuplicateException kde) {
            throw new ServiceAbortException(kde);
        }
    }

    /**
     * ???.
     * @param company 
     * @param user 
     * @return 
     */
    private CompanyUser createCompanyUser(Company company, User user) {
        CompanyUser updateCompanyUser = new CompanyUser();
        updateCompanyUser.setProjectCompanyId(company.getProjectCompanyId());
        updateCompanyUser.setProjectId(getCurrentProjectId());
        updateCompanyUser.setUser(user);
        updateCompanyUser.setCreatedBy(getCurrentUser());
        updateCompanyUser.setUpdatedBy(getCurrentUser());
        return updateCompanyUser;
    }

    /**
     * ??????.
     * @param company 
     * @throws ServiceAbortException ????????
     */
    private void validateDeleteMaster(Company company) throws ServiceAbortException {
        // SystemAdmin?
        validateNotSystemAdmin();
        // ?????????????
        validateRelationProject(company);
        // 0?? 
        findById(company.getId());
    }

    /**
     * ??????.
     * @param company 
     * @throws ServiceAbortException 
     */
    private void validateDeleteProject(Company company) throws ServiceAbortException {
        // ??[2]?
        validatePermission();
        // ??????
        validateProjectId(company.getProjectId());
        // ??????????????
        validateRelationUser(company);
        // 0??
        findProjectCompanyById(company.getId());
    }

    /**
     * ??????????.
     * @param company 
     * @return ?
     */
    private SearchCompanyCondition createCheckDeleteCondition(Company company) {
        SearchCompanyCondition condition = new SearchCompanyCondition();
        condition.setCompanyId(company.getId());
        return condition;
    }

    /**
     * ???.
     * @param id ID
     * @return ???ID
     * @throws ServiceAbortException ?
     */
    private Integer deleteCompany(Company company) throws ServiceAbortException {
        try {
            CompanyDao dao = getDao(CompanyDao.class);
            return dao.delete(company);
        } catch (KeyDuplicateException kde) {
            throw new ServiceAbortException(kde);
        } catch (StaleRecordException sre) {
            throw new ServiceAbortException(ApplicationMessageCode.CANNOT_PERFORM_BECAUSE_COMPANY_ALREADY_UPDATED);
        }
    }

    /**
     * ???.
     * @param id ID
     * @return ???ID
     * @throws ServiceAbortException ?
     */
    private Integer deleteProjectCompany(ProjectCompany projectCompany) throws ServiceAbortException {
        try {
            ProjectCompanyDao dao = getDao(ProjectCompanyDao.class);
            return dao.delete(projectCompany);
        } catch (KeyDuplicateException kde) {
            throw new ServiceAbortException(kde);
        } catch (StaleRecordException sre) {
            throw new ServiceAbortException(ApplicationMessageCode.CANNOT_PERFORM_BECAUSE_COMPANY_ALREADY_UPDATED);
        }
    }

    /**
     * ???.
     * @param company 
     * @return 
     */
    private Company createDeleteCompany(Company company) {
        Company deleteCompany = new Company();
        deleteCompany.setId(company.getId());
        deleteCompany.setUpdatedBy(getCurrentUser());
        deleteCompany.setVersionNo(company.getVersionNo());
        return deleteCompany;
    }

    /**
     * ???.
     * @param company 
     * @return 
     */
    private ProjectCompany createDeleteProjectCompany(Company company) {
        ProjectCompany pc = new ProjectCompany();
        pc.setId(company.getProjectCompanyId());
        pc.setUpdatedBy(getCurrentUser());
        return pc;
    }

    /**
     * ????.
     * @param company 
     * @return ?
     */
    private Company createExclusiveCheckCompany(Company company) {
        Company exclusiveCompany = new Company();
        exclusiveCompany.setId(company.getId());
        exclusiveCompany.setUpdatedBy(getCurrentUser());
        exclusiveCompany.setVersionNo(company.getVersionNo());
        return exclusiveCompany;
    }

    /**
     * ????????????.
     * @param company 
     * @throws ServiceAbortException ????
     */
    private void validateAlreadyCompanyProject(Company company) throws ServiceAbortException {
        Company c = null;
        // ???????????
        try {
            c = findProjectCompanyById(company.getId());
        } catch (ServiceAbortException sae) {
            // ??????????
            return;
        }
        if (c != null) {
            throw new ServiceAbortException(
                    ApplicationMessageCode.CANNOT_PERFORM_BECAUSE_COMPANY_ALREADY_ASSIGNED_TO_PROJECT);
        }
    }

    /**
     * SystemAdmin?.
     * @throws ServiceAbortException SystemAdmin????
     */
    private void validateNotSystemAdmin() throws ServiceAbortException {
        // SystemAdmin?
        if (!isSystemAdmin(getCurrentUser())) {
            throw new ServiceAbortException(
                    ApplicationMessageCode.CANNOT_PERFORM_BECAUSE_ACCESS_LEVEL_INSUFFICIENT);
        }
    }

    /**
     * ?????.
     * @param company 
     * @throws ServiceAbortException ??
     */
    private void validateExistCompanyCode(Company company) throws ServiceAbortException {
        SearchCompanyCondition condition = new SearchCompanyCondition();
        condition.setCompanyCd(company.getCompanyCd());
        // 
        if (!company.isNew()) {
            condition.setId(company.getId());
        }
        // ????company_cd??????
        if (countCheck(condition) > 0) {
            throw new ServiceAbortException(
                    ApplicationMessageCode.CANNOT_PERFORM_BECAUSE_COMPANY_CODE_ALREADY_EXISTS,
                    (Object) company.getCompanyCd());
        }
    }

    /**
     * ??????.
     * @param condition ?
     * @return 
     */
    private int countCheck(SearchCompanyCondition condition) {
        CompanyDao dao = getDao(CompanyDao.class);
        return dao.countCheck(condition);
    }

    /**
     * ?????????.
     * @param company 
     * @throws ServiceAbortException ???????
     */
    private void validateRelationProject(Company company) throws ServiceAbortException {
        // ?????????????
        if (countCheckProjectCompany(createCheckDeleteCondition(company)) > 0) {
            throw new ServiceAbortException(
                    ApplicationMessageCode.CANNOT_PERFORM_BECAUSE_COMPANY_ALREADY_ASSIGNED_TO_PROJECT);
        }
    }

    /**
     * ????????.
     * @param company 
     * @throws ServiceAbortException ??????
     */
    private void validateRelationUser(Company company) throws ServiceAbortException {
        // ??????????????
        List<CompanyUser> listCu = findCompanyMembers(company.getProjectCompanyId());
        if (listCu.size() != 0) {
            throw new ServiceAbortException(
                    ApplicationMessageCode.CANNOT_PERFORM_BECAUSE_COMPANY_ALREADY_RELATED_WITH_USER);
        }
    }

    /**
     * ????.
     * @param condition ?
     * @return 
     */
    private int countCheckProjectCompany(SearchCompanyCondition condition) {
        ProjectCompanyDao dao = getDao(ProjectCompanyDao.class);
        return dao.countCheck(condition);
    }

    /**
     * ????.
     * @param condition ?
     * @return 
     */
    private int countCheckProjectUser(SearchUserCondition condition) {
        UserDao dao = getDao(UserDao.class);
        return dao.countCheck(condition);
    }

    /**
     * ????????.
     * @param users 
     * @throws ServiceAbortException ????
     */
    private void validateUserExists(List<User> users) throws ServiceAbortException {
        SearchUserCondition condition = new SearchUserCondition();
        for (User user : users) {
            condition.setEmpNo(user.getEmpNo());
            if (countCheckProjectUser(condition) == 0) {
                throw new ServiceAbortException(ApplicationMessageCode.NO_DATA_FOUND);
            }
        }
    }
}