package pwc.taxtech.atms.service.impl; import org.apache.commons.io.FileUtils; import org.nutz.lang.Files; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import pwc.taxtech.atms.common.AuthUserHelper; import pwc.taxtech.atms.common.CommonConstants; import pwc.taxtech.atms.common.CommonUtils; import pwc.taxtech.atms.common.OperateLogType; import pwc.taxtech.atms.common.OperationAction; import pwc.taxtech.atms.common.OperationModule; import pwc.taxtech.atms.common.message.CustomerMessage; import pwc.taxtech.atms.dao.CustomerMapper; import pwc.taxtech.atms.dao.EnterpriseAccountSetMapper; import pwc.taxtech.atms.dto.OperationLogDto; import pwc.taxtech.atms.dto.OperationResultDto; import pwc.taxtech.atms.dto.UpdateLogParams; import pwc.taxtech.atms.dto.ValidateInfoDto; import pwc.taxtech.atms.dto.customer.CustomerDto; import pwc.taxtech.atms.dto.customer.CustomerValidateInfoDto; import pwc.taxtech.atms.dto.vatdto.CustomsInvoiceDto; import pwc.taxtech.atms.entity.Customer; import pwc.taxtech.atms.entity.CustomerExample; import pwc.taxtech.atms.entity.CustomerExample.Criteria; import pwc.taxtech.atms.entity.EnterpriseAccountSet; import pwc.taxtech.atms.exception.ApplicationException; import pwc.taxtech.atms.vat.dao.CustomsInvoiceMapper; import pwc.taxtech.atms.vat.entity.CustomsInvoice; import pwc.taxtech.atms.vat.entity.CustomsInvoiceExample; import java.io.File; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** */ @Service public class CustomerServiceImpl { private static final Logger logger = LoggerFactory.getLogger(CustomerServiceImpl.class); @Autowired private CustomerMapper customerMapper; @Autowired private AuthUserHelper authUserHelper; @Autowired private OperationLogServiceImpl operationLogService; @Autowired private EnterpriseAccountSetMapper enterpriseAccountSetMapper; @Autowired private FileService fileService; @Autowired private CustomsInvoiceMapper customsInvoiceMapper; public List<OperationResultDto<CustomerDto>> addRange(List<CustomerDto> customerDtoList) { logger.debug("CustomerService addRange"); // logger.debug("customer list to add:{}", JSON.toJSONString(customerDtoList, true)); if (customerDtoList == null) { throw new ApplicationException("input CustomerDto is null"); } List<OperationResultDto<CustomerDto>> errList = validateList(customerDtoList); if (!errList.isEmpty()) { return errList; } if (!customerDtoList.isEmpty()) { String enterPriseAccountId = customerDtoList.get(0).getEnterPriseAccountId(); String comment = getAccountNameById(enterPriseAccountId); for (CustomerDto customerDto : customerDtoList) { // insert record Customer customer = new Customer(); CommonUtils.copyProperties(customerDto, customer); customerMapper.insert(customer); // operation log OperationLogDto operationLogDto = new OperationLogDto(); makeUpOperationLogDto(operationLogDto); operationLogDto.setOperationObject( customerDto.getCode() + CommonConstants.PLUS_SIGN_SEPARATOR + customerDto.getName()); operationLogDto.setComment(comment); operationLogDto.setAction(OperationAction.New.value()); operationLogDto.setLogType(OperateLogType.OperationLogBasicData.value()); operationLogService.addOperationLog(operationLogDto); } } return errList; } private void makeUpOperationLogDto(OperationLogDto operationLogDto) { operationLogDto.setModule(OperationModule.BasicDataCustomer.value()); operationLogDto.setLogType(OperateLogType.OperationLogBasicData.value()); } public List<CustomerDto> getCustomer() { logger.debug("CustomerService getCustomer"); List<CustomerDto> customerDtoList = new ArrayList<>(); CustomerExample example = new CustomerExample(); example.setOrderByClause("code ASC, name ASC"); List<Customer> customerList = customerMapper.selectByExample(example); customerList.forEach(a -> { CustomerDto customerDto = new CustomerDto(); CommonUtils.copyProperties(a, customerDto); customerDtoList.add(customerDto); }); return customerDtoList; } public OperationResultDto<String> deleteRange(List<CustomerDto> customerDtoList) { logger.debug("CustomerService deleteRange"); // logger.debug("customer list to delete:{}", JSON.toJSONString(customerDtoList, true)); if (customerDtoList.isEmpty()) { throw new ApplicationException(CommonConstants.JSONNULLOBJECT); } List<OperationLogDto> operationLogDtoList = new ArrayList<>(); for (CustomerDto customerDto : customerDtoList) { Customer customer = customerMapper.selectByPrimaryKey(customerDto.getId()); if (customer == null) { throw new ApplicationException("can't find customer to delete, id: " + customerDto.getId()); } customerMapper.deleteByPrimaryKey(customerDto.getId()); operationLogDtoList.add(populateLogDto(customerDto)); } // add operation log operationLogService.addOperationLogList(operationLogDtoList); // return operation result OperationResultDto<String> operationResultDto = new OperationResultDto<>(); operationResultDto.setResult(true); return operationResultDto; } public List<OperationResultDto<CustomerDto>> updateRange(List<CustomerDto> customerDtoList) { logger.debug("CustomerService updateRange"); // logger.debug("customer list to update:{}", JSON.toJSONString(customerDtoList, true)); if (customerDtoList.isEmpty()) { throw new ApplicationException(CommonConstants.JSONNULLOBJECT); } List<OperationResultDto<CustomerDto>> errList = validateList(customerDtoList); if (!errList.isEmpty()) { return errList; } List<UpdateLogParams> updateLogParamsList = new ArrayList<>(); for (CustomerDto customerDto : customerDtoList) { Assert.notNull(customerDto.getId(), "customer id is null"); // check if customer existed Customer existedCustomer = customerMapper.selectByPrimaryKey(customerDto.getId()); if (existedCustomer == null) { OperationResultDto<CustomerDto> operationResultDto = new OperationResultDto<>(); operationResultDto.setResult(false); operationResultDto.setResultMsg(CustomerMessage.CannotFindCustomerById); errList.add(operationResultDto); return errList; } // keep origin customer for operation log Customer originCustomer = new Customer(); CommonUtils.copyProperties(existedCustomer, originCustomer); // update existedCustomer.setCode(customerDto.getCode()); existedCustomer.setName(customerDto.getName()); customerMapper.updateByPrimaryKey(existedCustomer); // operation log UpdateLogParams updateLogParams = new UpdateLogParams(); updateLogParams.setOperationObject( customerDto.getCode() + CommonConstants.PLUS_SIGN_SEPARATOR + customerDto.getName()); updateLogParams.setOriginalState(originCustomer); updateLogParams.setUpdateState(existedCustomer); updateLogParams.setOperationUser(authUserHelper.getCurrentAuditor().get()); updateLogParams.setOperationModule(OperationModule.BasicDataCustomer.value()); updateLogParams.setComment(getAccountNameById(customerDto.getEnterPriseAccountId())); updateLogParams.setOperationAction(OperationAction.Update.value()); updateLogParams.setOperateLogType(OperateLogType.OperationLogBasicData.value()); updateLogParamsList.add(updateLogParams); } updateLogParamsList.forEach(a -> operationLogService.updateDataAddLog(a)); return errList; } @SuppressWarnings("rawtypes") public Object upload(InputStream inputStream, String fileName, String action, String enterpriseAccountId) { logger.debug("导入excel文件开始, action:{}, enterpriseAccountId:{}", action, enterpriseAccountId); String filePath = FileUtils.getTempDirectory().getAbsolutePath() + File.separator + "customer" + File.separator + CommonUtils.getUUID() + "_" + fileName; OperationResultDto<Object> saveResult = fileService.saveFile(inputStream, filePath); if (saveResult.getResult() != null && !saveResult.getResult()) { return saveResult; } InputStream newInputStream = Files.findFileAsStream(filePath); Collection<Map> mapCollection = fileService.readExcelAndClose(newInputStream); List<CustomerDto> customerDtoList = new ArrayList<CustomerDto>(); for (Map map : mapCollection) { String name = map.get(CommonConstants.CUSTOMER_NAME) == null ? null : map.get(CommonConstants.CUSTOMER_NAME).toString(); String code = map.get(CommonConstants.CUSTOMER_CODE) == null ? null : map.get(CommonConstants.CUSTOMER_CODE).toString(); CustomerDto item = new CustomerDto(); item.setName(name); item.setCode(code); item.setId(CommonUtils.getUUID()); item.setEnterPriseAccountId(enterpriseAccountId); customerDtoList.add(item); } logger.debug("Map转为CustomerDto完毕, customerDtoList.size:{}", customerDtoList.size()); if (customerDtoList.isEmpty()) { logger.error("excel 导入出错,customerDtoList为空"); OperationResultDto<List<CustomerDto>> operationResultDto = new OperationResultDto<>(); String errorMsg = CustomerMessage.CustomerImportDataFormatError; Map<String, String> error = new HashMap<>(); error.put(CommonUtils.getUUID(), "文件导入出错"); operationResultDto.setErrors(error); operationResultDto.setResult(false); operationResultDto.setResultMsg(errorMsg); return operationResultDto; } // save data List<OperationResultDto<CustomerDto>> finalResult = saveData(enterpriseAccountId, customerDtoList, action); return finalResult; } public List<CustomsInvoiceDto> GetCustomsInvoicesByPeriodIds(int fromPeriod, int toPeriod) { CustomsInvoiceExample example = new CustomsInvoiceExample(); example.createCriteria().andPeriodIdGreaterThanOrEqualTo(fromPeriod).andPeriodIdLessThanOrEqualTo(toPeriod); List<CustomsInvoice> reuslt = customsInvoiceMapper.selectByExample(example); reuslt.stream().sorted(Comparator.comparing(CustomsInvoice::getPayNum)); List<CustomsInvoiceDto> returnResult = new ArrayList<>(); int seqNo = 1; for (CustomsInvoice r : reuslt) { CustomsInvoiceDto dto = new CustomsInvoiceDto(); dto.setSeqNo(seqNo++); if (r.getInvoiceAmount() != null) { r.setInvoiceAmount(r.getInvoiceAmount().setScale(2)); } if (r.getInvoiceTaxAmount() != null) { r.setInvoiceTaxAmount(r.getInvoiceTaxAmount().setScale(2)); } returnResult.add(dto.extractFromEntity(r)); } return returnResult; } private List<OperationResultDto<CustomerDto>> saveData(String enterpriseAccountId, List<CustomerDto> customerDtoList, String action) { logger.debug("enter customerDtoList, enterpriseAccountId:{}, customerDtoList.size:{}, action:{}", enterpriseAccountId, customerDtoList.size(), action); List<OperationResultDto<CustomerDto>> errList = new ArrayList<OperationResultDto<CustomerDto>>(); List<OperationResultDto<CustomerDto>> invalidList = new ArrayList<OperationResultDto<CustomerDto>>(); boolean overwriteFlag = false; if (CommonConstants.IMPORT_APPEND.equals(action)) { // no logic } else if (CommonConstants.IMPORT_OVERWRITE.equals(action)) { logger.debug("overwriteFlag is true"); overwriteFlag = true; } else { throw new ApplicationException("Invalid action:" + action); } for (CustomerDto customerDto : customerDtoList) { // 代码为空,不能进DB,名称为空,可以进DB if (!StringUtils.hasText(customerDto.getCode())) { OperationResultDto<CustomerDto> errorResult = new OperationResultDto<CustomerDto>(); errorResult.setResult(false); errorResult.setData(customerDto); errorResult.setResultMsg(CustomerMessage.CustomerCodeEmptyNode); logger.debug("代码为空"); errList.add(errorResult); } // 代码或者名称长度超过一定长度,不能进DB String errorMessage = checkLength(customerDto); if (StringUtils.hasText(errorMessage)) { OperationResultDto<CustomerDto> errorResult = new OperationResultDto<CustomerDto>(); errorResult.setResult(false); errorResult.setData(customerDto); errorResult.setResultMsg(errorMessage); logger.debug("代码或者名称长度超过一定长度"); errList.add(errorResult); } if (!StringUtils.hasText(customerDto.getName())) { OperationResultDto<CustomerDto> errorResult = new OperationResultDto<CustomerDto>(); errorResult.setResult(false); errorResult.setData(customerDto); errorResult.setResultMsg(CustomerMessage.CustomerNameEmptyNode); logger.debug("名称为空"); invalidList.add(errorResult); } } if (!CollectionUtils.isEmpty(errList)) { logger.debug("return errList"); return errList; } long start = System.currentTimeMillis(); if (overwriteFlag) { logger.debug("删除数据开始, overwriteFlag is {}, enterpriseAccountId:{}", overwriteFlag, enterpriseAccountId); CustomerExample example = new CustomerExample(); example.createCriteria().andEnterPriseAccountIdEqualTo(enterpriseAccountId); customerMapper.deleteByExample(example); logger.debug("删除数据结束"); } for (CustomerDto customerDto : customerDtoList) { CustomerExample example = new CustomerExample(); Criteria criteria = example.createCriteria(); criteria.andEnterPriseAccountIdEqualTo(enterpriseAccountId); criteria.andCodeEqualTo(customerDto.getCode()); List<Customer> existRecord = customerMapper.selectByExample(example); if (!CollectionUtils.isEmpty(existRecord)) { OperationResultDto<CustomerDto> errorResult = new OperationResultDto<CustomerDto>(); errorResult.setResult(false); errorResult.setResultMsg(CustomerMessage.SameCustomerExist); logger.debug("重复的记录"); invalidList.add(errorResult); } // BUGFIX 重复的记录可以进入数据库 2018-03-22 Customer customer = new Customer(); CommonUtils.copyProperties(customerDto, customer); logger.debug("insert start"); customerMapper.insert(customer); logger.debug("insert finished"); } OperationLogDto operationLogDto = new OperationLogDto(); operationLogDto.setOperationObject(getAccountNameById(enterpriseAccountId)); operationLogDto.setModule(OperationModule.BasicDataCustomer.value()); operationLogDto.setAction(OperationAction.New.value()); operationLogDto.setLogType(OperateLogType.OperationLogBasicData.value()); operationLogService.addOperationLog(operationLogDto); logger.debug("导入数据结束, 用时[{}ms]", System.currentTimeMillis() - start); return invalidList; } private OperationLogDto populateLogDto(CustomerDto customerDto) { OperationLogDto operationLogDto = new OperationLogDto(); makeUpOperationLogDto(operationLogDto); operationLogDto.setOperationObject( customerDto.getCode() + CommonConstants.PLUS_SIGN_SEPARATOR + customerDto.getName()); operationLogDto.setComment(customerDto.getEnterPriseAccountId()); operationLogDto.setAction(OperationAction.Delete.value()); return operationLogDto; } public CustomerValidateInfoDto getByEnterpriseAccountSetId(String setId) { logger.debug("CustomerService getByEnterpriseAccountSetId"); logger.debug("get customer by set id, id: {}", setId); if (setId == null) { throw new ApplicationException("enterprise account set id is null"); } CustomerValidateInfoDto customerValidateInfoDto = new CustomerValidateInfoDto(); CustomerExample example = new CustomerExample(); example.createCriteria().andEnterPriseAccountIdEqualTo(setId); example.setOrderByClause("code ASC, name ASC"); List<Customer> customerList = customerMapper.selectByExample(example); if (!customerList.isEmpty()) { List<CustomerDto> customerDtoList = new ArrayList<>(); customerValidateInfoDto.setCustomerList(customerDtoList); customerList.forEach(a -> { CustomerDto customerDto = new CustomerDto(); CommonUtils.copyProperties(a, customerDto); customerDtoList.add(customerDto); }); List<ValidateInfoDto> errorList = new ArrayList<>(); // 取出重复数据 getDuplicateData(customerDtoList, errorList); // 取出名称为空的数据 getEmptyName(customerDtoList, errorList); customerValidateInfoDto.setValidateInfoList(errorList); } return customerValidateInfoDto; } // 拿出名称为空的数据 private List<ValidateInfoDto> getEmptyName(List<CustomerDto> customerDtoList, List<ValidateInfoDto> errorList) { List<CustomerDto> newCustomerDtoList = new ArrayList<>(); customerDtoList.stream().filter(a -> StringUtils.isEmpty(a.getName())).forEach(newCustomerDtoList::add); if (!newCustomerDtoList.isEmpty()) { List<String> codeList = new ArrayList<>(); newCustomerDtoList.forEach(a -> codeList.add(a.getCode())); ValidateInfoDto errDto = new ValidateInfoDto(); errDto.setType(CustomerMessage.CustomerNameEmptyNode); errDto.setInValidateCodeList(codeList); errorList.add(errDto); } return errorList; } // 根据代码取出重复数据 private List<ValidateInfoDto> getDuplicateData(List<CustomerDto> customerDtoList, List<ValidateInfoDto> errorList) { List<CustomerDto> newCustomerDtoList = new ArrayList<>(); customerDtoList.stream().collect(Collectors.groupingBy(CustomerDto::getCode, Collectors.toList())) .forEach((code, list) -> { if (list.size() > 1) { newCustomerDtoList.add(list.get(0)); } }); if (!newCustomerDtoList.isEmpty()) { List<String> codeList = new ArrayList<>(); newCustomerDtoList.forEach(a -> codeList.add(a.getCode())); ValidateInfoDto errDto = new ValidateInfoDto(); errDto.setType(CustomerMessage.SameCustomerExist); errDto.setInValidateCodeList(codeList); errorList.add(errDto); } return errorList; } // Get EnterPrise Account Name by id private String getAccountNameById(String enterPriseAccountId) { String enterpriseAccountName = null; if (StringUtils.isEmpty(enterPriseAccountId)) { return enterpriseAccountName; } EnterpriseAccountSet enterpriseAccountSet = enterpriseAccountSetMapper.selectByPrimaryKey(enterPriseAccountId); if (enterpriseAccountSet == null) { return enterpriseAccountName; } enterpriseAccountName = enterpriseAccountSet.getName(); return enterpriseAccountName; } private List<OperationResultDto<CustomerDto>> validateList(List<CustomerDto> customerDtoList) { List<OperationResultDto<CustomerDto>> errList = new ArrayList<>(); List<CustomerDto> distinctList = new ArrayList<>(); // group by customer name and get first record for each group customerDtoList.stream().collect(Collectors.groupingBy(CustomerDto::getName, Collectors.toList())) .forEach((name, customerList) -> distinctList.add(customerList.get(0))); // validate customerDto name and code: null and length for (CustomerDto customerDto : customerDtoList) { OperationResultDto<CustomerDto> validateResult = validateIsEmpty(customerDto); if (!validateResult.getResult()) { distinctList.remove(customerDto); errList.add(validateResult); } } // region customer validation List<CustomerDto> duplicateList = getDuplicate(customerDtoList); duplicateList.forEach(a -> { OperationResultDto<CustomerDto> operationResultDto = new OperationResultDto<>(); operationResultDto.setResult(false); operationResultDto.setResultMsg(CustomerMessage.SameCustomerExist); operationResultDto.setData(a); errList.add(operationResultDto); }); customerDtoList = distinctList; return errList; } private List<CustomerDto> getDuplicate(List<CustomerDto> customerDtoList) { List<CustomerDto> duplicateList = new ArrayList<>(); // group by customer code and if count in group > 1, then get the first record // in the group customerDtoList.stream().collect(Collectors.groupingBy(CustomerDto::getCode, Collectors.toList())) .forEach((code, groupedList) -> { if (groupedList.size() > 1) { duplicateList.add(groupedList.get(0)); } }); for (CustomerDto customerDto : customerDtoList) { List<CustomerDto> dup = checkDuplicate(customerDto); if (!dup.isEmpty() && !duplicateList.contains(customerDto)) { duplicateList.add(customerDto); } } return duplicateList; } // The customer code cannot be duplicated under the same enterpriseAccount private List<CustomerDto> checkDuplicate(CustomerDto customerDto) { List<CustomerDto> customerDtoList = new ArrayList<>(); CustomerExample example = new CustomerExample(); customerDto.getEnterPriseAccountId(); example.createCriteria().andEnterPriseAccountIdEqualTo(customerDto.getEnterPriseAccountId()) .andCodeEqualTo(customerDto.getCode()).andIdNotEqualTo(customerDto.getId()); List<Customer> customerList = customerMapper.selectByExample(example); customerList.forEach(a -> { CustomerDto dto = new CustomerDto(); dto.setCode(a.getCode()); dto.setEnterPriseAccountId(a.getEnterPriseAccountId()); dto.setId(a.getId()); dto.setName(a.getName()); customerDtoList.add(dto); }); return customerDtoList; } private OperationResultDto<CustomerDto> validateIsEmpty(CustomerDto customerDto) { String errMsg = null; OperationResultDto<CustomerDto> operationResultDto = new OperationResultDto<>(); errMsg = checkEmpty(customerDto); if (!StringUtils.isEmpty(errMsg)) { operationResultDto.setResult(false); operationResultDto.setResultMsg(errMsg); operationResultDto.setData(customerDto); } errMsg = checkLength(customerDto); if (!StringUtils.isEmpty(errMsg)) { operationResultDto.setResult(false); operationResultDto.setResultMsg(errMsg); operationResultDto.setData(customerDto); } operationResultDto.setResult(true); return operationResultDto; } private String checkLength(CustomerDto customerDto) { String errMsg = null; if (StringUtils.hasText(customerDto.getCode()) && customerDto.getCode().length() > CommonConstants.CODE_MAX_LENGTH) { errMsg = CustomerMessage.CodeOutOfLength; } if (StringUtils.hasText(customerDto.getName()) && customerDto.getName().length() > CommonConstants.NAME_MAX_LENGTH) { errMsg = CustomerMessage.NameOutOfLength; } return errMsg; } private String checkEmpty(CustomerDto customerDto) { String errMsg = null; if (StringUtils.isEmpty(customerDto.getCode())) { errMsg = CustomerMessage.CustomerCodeEmptyNode; } if (StringUtils.isEmpty(customerDto.getName())) { errMsg = CustomerMessage.CustomerNameEmptyNode; } return errMsg; } }