拆分模块

This commit is contained in:
2025-09-03 20:56:44 +08:00
parent 08cc2c29a5
commit a2f5e4864b
939 changed files with 14227 additions and 9607 deletions

View File

@@ -0,0 +1,863 @@
package com.ecep.contract.task;
import java.io.File;
import java.text.NumberFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.DoubleSummaryStatistics;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.stream.Collectors;
import org.hibernate.Hibernate;
import org.springframework.util.StringUtils;
import com.ecep.contract.CompanyCustomerFileType;
import com.ecep.contract.ContractFileType;
import com.ecep.contract.ContractPayWay;
import com.ecep.contract.Desktop;
import com.ecep.contract.MessageHolder;
import com.ecep.contract.MyDateTimeUtils;
import com.ecep.contract.SpringApp;
import com.ecep.contract.ds.project.ProjectCostImportItemsFromContractsTasker;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyCustomer;
import com.ecep.contract.model.CompanyCustomerFile;
import com.ecep.contract.model.CompanyExtendInfo;
import com.ecep.contract.model.Contract;
import com.ecep.contract.model.ContractBidVendor;
import com.ecep.contract.model.ContractFile;
import com.ecep.contract.model.ContractFileTypeLocal;
import com.ecep.contract.model.Employee;
import com.ecep.contract.model.ExtendVendorInfo;
import com.ecep.contract.model.Project;
import com.ecep.contract.model.ProjectBid;
import com.ecep.contract.model.ProjectCost;
import com.ecep.contract.model.ProjectQuotation;
import com.ecep.contract.model.ProjectSaleType;
import com.ecep.contract.model.ProjectSaleTypeRequireFileType;
import com.ecep.contract.model.VendorGroup;
import com.ecep.contract.model.VendorGroupRequireFileType;
import com.ecep.contract.service.CompanyCustomerService;
import com.ecep.contract.service.CompanyFileService;
import com.ecep.contract.service.CompanyService;
import com.ecep.contract.service.CompanyVendorService;
import com.ecep.contract.service.ContractBidVendorService;
import com.ecep.contract.service.ContractFileService;
import com.ecep.contract.service.ContractService;
import com.ecep.contract.service.EmployeeService;
import com.ecep.contract.service.ExtendVendorInfoService;
import com.ecep.contract.service.ProjectBidService;
import com.ecep.contract.service.ProjectCostService;
import com.ecep.contract.service.ProjectQuotationService;
import com.ecep.contract.service.ProjectSaleTypeRequireFileTypeService;
import com.ecep.contract.service.ProjectSaleTypeService;
import com.ecep.contract.service.ProjectService;
import com.ecep.contract.service.VendorGroupRequireFileTypeService;
import com.ecep.contract.service.VendorGroupService;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableMap;
import javafx.util.converter.NumberStringConverter;
import lombok.Data;
@Data
public class ContractVerifyComm {
// Project
private ProjectService projectService;
private ProjectSaleTypeRequireFileTypeService saleTypeRequireFileTypeService;
private ProjectSaleTypeService saleTypeService;
private ProjectCostService projectCostService;
private ProjectQuotationService projectQuotationService;
private ProjectBidService projectBidService;
// Contract
private ContractService contractService;
private ContractFileService contractFileService;
private ContractBidVendorService contractBidVendorService;
// Company
private CompanyService companyService;
private CompanyFileService companyFileService;
// Vendor
private CompanyVendorService companyVendorService;
private VendorGroupService vendorGroupService;
private VendorGroupRequireFileTypeService vendorGroupRequireFileTypeService;
private ExtendVendorInfoService extendVendorInfoService;
// Customer
private CompanyCustomerService companyCustomerService;
private CompanyCustomerFileService companyCustomerFileService;
private CompanyExtendInfoService companyExtendInfoService;
// Employee
private EmployeeService employeeService;
private ProjectService getProjectService() {
if (projectService == null) {
projectService = SpringApp.getBean(ProjectService.class);
}
return projectService;
}
private ProjectSaleTypeService getSaleTypeService() {
if (saleTypeService == null) {
saleTypeService = SpringApp.getBean(ProjectSaleTypeService.class);
}
return saleTypeService;
}
ProjectCostService getProjectCostService() {
if (projectCostService == null) {
projectCostService = SpringApp.getBean(ProjectCostService.class);
}
return projectCostService;
}
ProjectQuotationService getProjectQuotationService() {
if (projectQuotationService == null) {
projectQuotationService = SpringApp.getBean(ProjectQuotationService.class);
}
return projectQuotationService;
}
ProjectBidService getProjectBidService() {
if (projectBidService == null) {
projectBidService = SpringApp.getBean(ProjectBidService.class);
}
return projectBidService;
}
private ProjectSaleTypeRequireFileTypeService getSaleTypeRequireFileTypeService() {
if (saleTypeRequireFileTypeService == null) {
saleTypeRequireFileTypeService = SpringApp.getBean(ProjectSaleTypeRequireFileTypeService.class);
}
return saleTypeRequireFileTypeService;
}
public ContractService getContractService() {
if (contractService == null) {
contractService = SpringApp.getBean(ContractService.class);
}
return contractService;
}
private ContractFileService getContractFileService() {
if (contractFileService == null) {
contractFileService = SpringApp.getBean(ContractFileService.class);
}
return contractFileService;
}
private ContractBidVendorService getContractBidVendorService() {
if (contractBidVendorService == null) {
contractBidVendorService = SpringApp.getBean(ContractBidVendorService.class);
}
return contractBidVendorService;
}
private CompanyService getCompanyService() {
if (companyService == null) {
companyService = SpringApp.getBean(CompanyService.class);
}
return companyService;
}
private CompanyFileService getCompanyFileService() {
if (companyFileService == null) {
companyFileService = SpringApp.getBean(CompanyFileService.class);
}
return companyFileService;
}
private VendorGroupService getVendorGroupService() {
if (vendorGroupService == null) {
vendorGroupService = SpringApp.getBean(VendorGroupService.class);
}
return vendorGroupService;
}
private VendorGroupRequireFileTypeService getVendorGroupRequireFileTypeService() {
if (vendorGroupRequireFileTypeService == null) {
vendorGroupRequireFileTypeService = SpringApp.getBean(VendorGroupRequireFileTypeService.class);
}
return vendorGroupRequireFileTypeService;
}
private ExtendVendorInfoService getExtendVendorInfoService() {
if (extendVendorInfoService == null) {
extendVendorInfoService = SpringApp.getBean(ExtendVendorInfoService.class);
}
return extendVendorInfoService;
}
private CompanyVendorService getCompanyVendorService() {
if (companyVendorService == null) {
companyVendorService = SpringApp.getBean(CompanyVendorService.class);
}
return companyVendorService;
}
private CompanyCustomerService getCompanyCustomerService() {
if (companyCustomerService == null) {
companyCustomerService = SpringApp.getBean(CompanyCustomerService.class);
}
return companyCustomerService;
}
private CompanyCustomerFileService getCompanyCustomerFileService() {
if (companyCustomerFileService == null) {
companyCustomerFileService = SpringApp.getBean(CompanyCustomerFileService.class);
}
return companyCustomerFileService;
}
private CompanyExtendInfoService getCompanyExtendInfoService() {
if (companyExtendInfoService == null) {
companyExtendInfoService = SpringApp.getBean(CompanyExtendInfoService.class);
}
return companyExtendInfoService;
}
private EmployeeService getEmployeeService() {
if (employeeService == null) {
employeeService = SpringApp.getBean(EmployeeService.class);
}
return employeeService;
}
/**
*
*/
private ObservableMap<ContractFileType, ContractFileTypeLocal> fileTypeLocalMap = null;
private Locale locale = Locale.getDefault();
private Contract contract;
/**
* 是否验证企业存储目录
*/
private SimpleBooleanProperty verifyCompanyPath = new SimpleBooleanProperty(true);
/**
* 是否验证企业状态
*/
private SimpleBooleanProperty verifyCompanyStatus = new SimpleBooleanProperty(true);
/**
* 是否验证企业文件(资信报告)
*/
private SimpleBooleanProperty verifyCompanyCredit = new SimpleBooleanProperty(true);
/**
* 是否验证客户
*/
private SimpleBooleanProperty verifyCustomer = new SimpleBooleanProperty(true);
/**
* 是否验证客户文件(合同文件)
*/
private SimpleBooleanProperty verifyCustomerFiles = new SimpleBooleanProperty(true);
/**
* 是否验证客户子合同日期
*/
private SimpleBooleanProperty verifyCustomerSubContractDate = new SimpleBooleanProperty(true);
/**
* 是否验证供应商
*/
private SimpleBooleanProperty verifyVendor = new SimpleBooleanProperty(true);
/**
* 是否验证供应商文件(供应商合同)
*/
private SimpleBooleanProperty verifyVendorFiles = new SimpleBooleanProperty(true);
/**
* 合同合规性检测
*
* @param contract 要验证的合同对象
* @param holder 输出
*/
public void verify(Contract contract, MessageHolder holder) {
LocalDate setupDate = contract.getSetupDate();
if (setupDate == null) {
holder.error("未设置合同提交日期");
return;
}
Company company = contract.getCompany();
if (company == null) {
holder.error("未关联企业");
return;
}
if (!Hibernate.isInitialized(company)) {
company = getCompanyService().findById(company.getId());
}
verify(company, contract, holder);
}
public void verify(Company company, Contract contract, MessageHolder holder) {
LocalDate setupDate = contract.getSetupDate();
Employee employee = contract.getEmployee();
if (employee == null) {
holder.error("未关联业务员");
}
if (contract.getAmount() == null || contract.getAmount() <= 0) {
holder.error("合同金额小于等于0");
}
CompanyExtendInfo companyExtendInfo = getCompanyExtendInfoService().findByCompany(company);
if (companyExtendInfo.isDisableVerify()) {
holder.debug("公司设定不做校验");
} else {
if (verifyCompanyPath.get()) {
if (!CompanyFileUtils.exists(company.getPath())) {
holder.error("公司目录未设置");
} else {
File basePath = getCompanyService().getBasePath();
if (!company.getPath().startsWith(basePath.getAbsolutePath())) {
holder.error("公司目录未在规定目录下");
}
}
}
if (verifyCompanyStatus.get()) {
getCompanyService().verifyEnterpriseStatus(company, setupDate, msg -> {
holder.error(company.getName() + ":" + msg);
});
}
if (verifyCompanyCredit.get()) {
getCompanyFileService().verify(company, contract.getSetupDate(), msg -> {
holder.error(company.getName() + ":" + msg);
});
}
}
// 合同类型
switch (contract.getPayWay()) {
case RECEIVE -> {
// 销售合同
verifyAsCustomer(company, companyExtendInfo, contract, holder);
// 销售合同下的采购合同
List<Contract> list = getContractService().findAllByParent(contract);
if (!list.isEmpty()) {
for (Contract v : list) {
MessageHolder subHolder = holder.sub(v.getCode() + " -> ");
subHolder.info("采购合同 " + v.getName());
verify(v, subHolder);
if (CompanyFileUtils.exists(v.getPath())) {
if (!v.getPath().startsWith(contract.getPath())) {
holder.error("合同目录未在规定目录下");
}
} else {
holder.error("合同目录未设置");
}
}
DoubleSummaryStatistics statistics = list.stream().mapToDouble(c -> {
return Objects.requireNonNullElse(c.getAmount(), 0.0);
}).summaryStatistics();
NumberFormat numberFormat = NumberFormat.getCurrencyInstance(locale);
holder.debug("采购合同金额合计:" + numberFormat.format(statistics.getSum()));
holder.debug("采购合同金额平均值:" + numberFormat.format(statistics.getAverage()));
holder.debug("采购合同金额最大值:" + numberFormat.format(statistics.getMax()));
holder.debug("采购合同金额最小值:" + numberFormat.format(statistics.getMin()));
if (contract.getAmount() != null && statistics.getSum() > contract.getAmount()) {
holder.warn("采购合同金额合计大于销售合同金额");
}
}
break;
}
case PAY -> {
verifyAsVendor(company, contract, holder);
break;
}
case OTHER -> {
holder.error("合同付款类型:其他");
break;
}
default -> {
holder.error("合同付款类型:未设置");
}
}
}
private void verifyAsVendor(Company company, Contract contract, MessageHolder holder) {
// 供应商,检查评价表
ExtendVendorInfo vendorInfo = getExtendVendorInfoService().findByContract(contract);
if (vendorInfo == null) {
ExtendVendorInfo info = getExtendVendorInfoService().newInstanceByContract(contract);
vendorInfo = getExtendVendorInfoService().save(info);
holder.info("创建供应商信息 #" + vendorInfo.getId());
}
VendorGroup group = vendorInfo.getGroup();
boolean assignedProvider = vendorInfo.isAssignedProvider();
if (assignedProvider) {
holder.debug("采购信息中设定为指定供应商");
}
if (group != null) {
if (!Hibernate.isInitialized(group)) {
group = getVendorGroupService().findById(group.getId());
vendorInfo.setGroup(group);
}
}
if (verifyCustomerSubContractDate.get()) {
// 检查子合同日期是否在销售合同之后
if (!vendorInfo.isPrePurchase()) {
String parentCode = contract.getParentCode();
if (StringUtils.hasText(parentCode)) {
Contract parent = getContractService().findByCode(parentCode);
if (parent != null) {
if (contract.getSetupDate().isBefore(parent.getSetupDate())) {
holder.warn("采购合同:" + contract.getCode() + " 提交日期在销售合同之前");
}
}
}
}
}
if (verifyVendor.get()) {
getCompanyVendorService().verify(contract, holder);
}
if (verifyVendorFiles.get()) {
holder.debug("核验文件...");
verifyVendorFile(group, assignedProvider, contract, holder);
}
}
private void verifyVendorFile(VendorGroup group, boolean assignedProvider, Contract contract,
MessageHolder holder) {
if (group == null) {
return;
}
boolean loseFile = false;
List<ContractFile> files = getContractFileService().findAllByContract(contract);
List<VendorGroupRequireFileType> list = getVendorGroupRequireFileTypeService().findByGroupId(group.getId());
if (list != null && !list.isEmpty()) {
for (VendorGroupRequireFileType item : list) {
ContractFileType fileType = item.getFileType();
if (fileType == null) {
continue;
}
if (fileType == ContractFileType.QuotationSheet && assignedProvider
&& group.isRequireQuotationSheetForBid()) {
continue;
}
if (!hasFileType(files, fileType)) {
holder.error("供应商" + getFileTypeLocalValue(fileType) + "未上传");
loseFile = true;
}
}
}
// 供应商比价
if (group.isPriceComparison()) {
if (assignedProvider) {
holder.debug("指定供应商, 跳过供应商比价");
} else {
boolean requireQuotation = group.isRequireQuotationSheetForBid();
List<ContractBidVendor> bidVendors = getContractBidVendorService().findByContract(contract);
if (bidVendors == null || bidVendors.isEmpty()) {
holder.error("未上报供应商比价");
} else {
for (ContractBidVendor bidVendor : bidVendors) {
ContractFile contractFile = bidVendor.getQuotationSheet();
if (contractFile == null) {
if (requireQuotation && bidVendor.getCompany().equals(contract.getCompany())) {
holder.debug("供应商类型启用了允许选中供应商不必须要有报价表");
} else {
holder.error("供应商比价:" + bidVendor.getCompany().getName() + " 未上传/关联报价表");
loseFile = true;
}
} else {
if (!Hibernate.isInitialized(contractFile)) {
contractFile = getContractFileService().findById(contractFile.getId());
}
ContractFileType type = contractFile.getType();
if (type != ContractFileType.QuotationSheet) {
holder.error("供应商比价:" + contractFile.getFileName() + " 报价表记录异常,类型错误");
}
File file = new File(contract.getPath(), contractFile.getFileName());
if (!file.exists()) {
holder.error("供应商比价:" + file.getName() + " 报价表记录异常,文件不存在");
loseFile = true;
}
}
}
}
}
}
if (loseFile && files.isEmpty()) {
holder.warn("!上传文件空!");
}
}
ContractFileTypeLocal getFileTypeLocal(ContractFileType type) {
if (fileTypeLocalMap == null) {
fileTypeLocalMap = FXCollections
.observableMap(getContractFileService().findAllFileTypes(getLocale().toLanguageTag()));
}
return fileTypeLocalMap.get(type);
}
String getFileTypeLocalValue(ContractFileType type) {
ContractFileTypeLocal fileTypeLocal = getFileTypeLocal(type);
if (fileTypeLocal == null) {
return type.name();
}
return fileTypeLocal.getValue();
}
private boolean hasFileType(List<ContractFile> files, ContractFileType fileType) {
if (files == null || files.isEmpty()) {
return false;
}
for (ContractFile file : files) {
if (file.getType() == fileType) {
return true;
}
}
return false;
}
private void verifyAsCustomer(Company company, CompanyExtendInfo companyExtendInfo, Contract contract,
MessageHolder holder) {
boolean valiad = true;
Project project = contract.getProject();
if (project == null) {
// 收款的合同时,检查是否关联了项目,如果没有则创建
if (contract.getPayWay() == ContractPayWay.RECEIVE) {
project = getProjectService().findByCode(contract.getCode());
if (project == null) {
holder.info("创建关联项目");
try {
project = getProjectService().newInstanceByContract(contract);
project = getProjectService().save(project);
} catch (Exception e) {
holder.error("创建关联项目失败: " + e.getMessage());
throw new RuntimeException("code=" + contract.getCode(), e);
}
}
contract.setProject(project);
contract = getContractService().save(contract);
}
}
if (project != null) {
if (!Hibernate.isInitialized(project)) {
project = getProjectService().findById(project.getId());
// fixed
contract.setProject(project);
}
}
if (project != null) {
holder.info("验证项目信息:" + project.getCode() + " " + project.getName());
verifyProject(contract, project, holder.sub("项目"));
ProjectSaleType saleType = project.getSaleType();
if (saleType != null) {
if (CompanyFileUtils.exists(contract.getPath())) {
if (!Hibernate.isInitialized(saleType)) {
saleType = getSaleTypeService().findById(saleType.getId());
project.setSaleType(saleType);
}
if (!contract.getPath().startsWith(saleType.getPath())) {
holder.error("合同目录未在销售类型目录下");
}
}
}
}
if (!companyExtendInfo.isDisableVerify()) {
if (!verifyCustomerContract(contract, holder)) {
valiad = false;
}
if (verifyCustomerFiles.get()) {
holder.debug("核验文件...");
if (!verifyContractFileAsCustomer(project, contract, holder)) {
valiad = false;
}
}
}
}
/**
* 客户,检查评估表
*/
private boolean verifyCustomerContract(Contract contract, MessageHolder holder) {
if (!verifyCustomer.get()) {
return false;
}
boolean valid = true;
Company company = contract.getCompany();
if (company == null) {
holder.warn("合同未关联公司");
valid = false;
}
CompanyCustomer companyCustomer = getCompanyCustomerService().findByCompany(company);
if (companyCustomer == null) {
holder.warn("合同未关联客户");
valid = false;
} else {
if (!StringUtils.hasText(companyCustomer.getPath())) {
holder.warn("客户未设置文件夹");
valid = false;
}
LocalDate developDate = companyCustomer.getDevelopDate();
if (developDate == null) {
holder.warn("客户未设置开发日期");
valid = false;
}
if (!verifyCustomerFileByContract(companyCustomer, contract, holder)) {
valid = false;
}
}
return valid;
}
private boolean verifyCustomerFileByContract(CompanyCustomer companyCustomer, Contract contract,
MessageHolder holder) {
List<LocalDate> verifyDates = new ArrayList<>();
LocalDate minDate = LocalDate.of(2022, 1, 1);
LocalDate developDate = companyCustomer.getDevelopDate();
if (developDate != null) {
if (developDate.isAfter(minDate)) {
minDate = developDate;
}
}
if (contract.getSetupDate() != null) {
LocalDate setupDate = contract.getSetupDate();
if (setupDate.isBefore(developDate)) {
holder.error("合同提交日期 " + setupDate + " 早于客户开发日期 " + developDate + ".");
return false;
}
if (setupDate.isBefore(minDate)) {
holder.debug("合同提交日期 " + setupDate + " 早于 " + minDate + ", 跳过");
} else {
verifyDates.add(setupDate);
}
}
if (contract.getStartDate() != null) {
LocalDate startDate = contract.getStartDate();
if (startDate.isBefore(developDate)) {
holder.warn("合同起始日期 " + startDate + " 早于客户开发日期 " + developDate + ".");
}
if (startDate.isBefore(minDate)) {
holder.debug("合同起始日期 " + startDate + " 早于 " + minDate + ", 跳过");
} else {
verifyDates.add(startDate);
}
}
if (contract.getOrderDate() != null) {
LocalDate orderDate = contract.getOrderDate();
if (orderDate.isBefore(developDate)) {
holder.error("合同签订日期 " + orderDate + " 早于客户开发日期 " + developDate + ".");
return false;
}
if (orderDate.isBefore(minDate)) {
holder.debug("合同签订日期 " + orderDate + " 早于 " + minDate + ", 跳过");
} else {
verifyDates.add(orderDate);
}
}
if (verifyDates.isEmpty()) {
holder.warn("合同没有符合可核验的日期");
return false;
}
// 客户
List<CompanyCustomerFile> files = getCompanyCustomerFileService().findAllByCustomer(companyCustomer);
if (files == null || files.isEmpty()) {
holder.warn("未见客户评估表");
return false;
}
for (LocalDate verifyDate : verifyDates) {
CompanyCustomerFile customerFile = files.stream()
.filter(v -> v.getSignDate() != null && v.isValid())
.filter(v -> v.getType() == CompanyCustomerFileType.EvaluationForm)
.filter(v -> MyDateTimeUtils.dateValidFilter(verifyDate, v.getSignDate(),
v.getSignDate().plusYears(1), 7))
.findFirst().orElse(null);
if (customerFile != null) {
return true;
}
}
CompanyCustomerFile latestFile = files.stream()
.filter(v -> v.getSignDate() != null && v.isValid())
.filter(v -> v.getType() == CompanyCustomerFileType.EvaluationForm)
.max(Comparator.comparing(CompanyCustomerFile::getSignDate))
.orElse(null);
if (latestFile == null) {
holder.error("未匹配的客户评估");
return false;
}
holder.error("客户评估已过期,最后一个客户评估报告日期:" + latestFile.getSignDate() + ", 检测日期:"
+ verifyDates.stream().map(LocalDate::toString).collect(Collectors.joining(", ")));
return false;
}
private void verifyProject(Contract contract, Project project, MessageHolder holder) {
ProjectSaleType saleType = project.getSaleType();
if (saleType == null) {
String code = contract.getCode();
if (code != null && code.length() > 5) {
saleType = getSaleTypeService().findByCode(code.substring(0, 1));
}
}
if (saleType == null) {
holder.warn("销售类型未设置");
}
if (project.getAmount() == null || project.getAmount() <= 0) {
holder.error("金额小于等于0");
}
//
boolean needImport = false;
ProjectCost autoCost = getProjectCostService().findAutoCostByProject(project);
if (autoCost == null) {
// 创建 V0 项目成本
ProjectCost cost = getProjectCostService().newInstanceByProject(project);
cost.setVersion(0);
cost.setApplicant(getEmployeeService().findById(EmployeeService.DEFAULT_SYSTEM_EMPLOYEE_ID));
cost.setApplyTime(LocalDateTime.now());
cost.setDescription("自动导入");
autoCost = getProjectCostService().save(cost);
needImport = true;
} else {
// 检查 V0 项目成本
if (autoCost.getGrossProfitMargin() <= 0) {
NumberFormat instance = NumberFormat.getNumberInstance(getLocale());
instance.setMaximumFractionDigits(2);
NumberStringConverter converter = new NumberStringConverter(instance);
holder.warn("V0项目成本毛利率异常" + converter.toString(autoCost.getGrossProfitMargin()) + "<=0%");
needImport = true;
}
}
if (needImport && !autoCost.isImportLock()) {
ProjectCostImportItemsFromContractsTasker tasker = new ProjectCostImportItemsFromContractsTasker();
tasker.setCost(autoCost);
tasker.setCurrentUser(() -> getEmployeeService().findById(Desktop.instance.getActiveEmployeeId()));
autoCost.setApplyTime(LocalDateTime.now());
holder.debug("更新V0项目成本");
Desktop.instance.getTaskMonitorCenter().registerAndStartTask(tasker);
}
// 检查最新的项目成本,默认 V1
ProjectCost latestCost = getProjectCostService().findLatestByProject(project);
if (latestCost == null) {
ProjectCost cost = getProjectCostService().newInstanceByProject(project);
cost.setVersion(1);
Employee applicant = project.getApplicant();
if (applicant == null) {
applicant = contract.getEmployee();
}
cost.setApplicant(applicant);
cost.setApplyTime(project.getCreated().atTime(LocalTime.now()));
latestCost = getProjectCostService().save(cost);
} else {
//
if (latestCost.getGrossProfitMargin() <= 0) {
NumberFormat instance = NumberFormat.getNumberInstance(getLocale());
instance.setMaximumFractionDigits(2);
NumberStringConverter converter = new NumberStringConverter(instance);
holder.warn("V" + latestCost.getVersion() + "项目成本毛利率异常:"
+ converter.toString(latestCost.getGrossProfitMargin()) + "<=0%");
} else if (latestCost.getGrossProfitMargin() >= 50) {
NumberFormat instance = NumberFormat.getNumberInstance(getLocale());
instance.setMaximumFractionDigits(2);
NumberStringConverter converter = new NumberStringConverter(instance);
holder.warn("V" + latestCost.getVersion() + "项目成本毛利率异常:"
+ converter.toString(latestCost.getGrossProfitMargin()) + ">=50%");
}
}
if (project.isUseBid()) {
List<ProjectBid> bids = getProjectBidService().findAllByProject(project);
if (bids.isEmpty()) {
holder.warn("投标未创建");
}
}
if (project.isUseOffer()) {
List<ProjectQuotation> quotations = getProjectQuotationService().findAllByProject(project);
if (quotations.isEmpty()) {
holder.warn("报价未创建");
}
}
}
private boolean verifyContractFileAsCustomer(Project project, Contract contract, MessageHolder holder) {
boolean loseFile = false;
List<ContractFile> files = getContractFileService().findAllByContract(contract);
if (project != null) {
// 投标
if (project.isUseBid()) {
// 投标审批表
if (!hasFileType(files, ContractFileType.BidApprovalForm)) {
holder.error(getFileTypeLocalValue(ContractFileType.BidApprovalForm) + "未上传");
loseFile = true;
}
// 中标通知书
if (!hasFileType(files, ContractFileType.BidAcceptanceLetter)) {
holder.error(getFileTypeLocalValue(ContractFileType.BidAcceptanceLetter) + "未上传");
loseFile = true;
}
}
// 报价
if (project.isUseOffer()) {
if (!hasFileType(files, ContractFileType.QuotationApprovalForm)) {
holder.error(getFileTypeLocalValue(ContractFileType.QuotationApprovalForm) + "未上传");
loseFile = true;
}
}
ProjectSaleType saleType = project.getSaleType();
if (saleType != null) {
List<ProjectSaleTypeRequireFileType> list = getSaleTypeRequireFileTypeService()
.findBySaleTypeId(saleType.getId());
for (ProjectSaleTypeRequireFileType item : list) {
ContractFileType fileType = item.getFileType();
if (fileType != null) {
if (!hasFileType(files, fileType)) {
holder.error(getFileTypeLocalValue(fileType) + "未上传");
loseFile = true;
}
}
}
if (!Hibernate.isInitialized(saleType)) {
saleType = getSaleTypeService().findById(saleType.getId());
}
if (saleType.isCriticalProjectDecision()) {
if (contract.getAmount() != null && contract.getAmount() >= saleType.getCriticalProjectLimit()) {
holder.debug("合同金额 " + contract.getAmount() + " 超过 " + saleType.getCriticalProjectLimit());
if (!hasFileType(files, ContractFileType.CriticalProjectDecisionRecord)) {
holder.error(getFileTypeLocalValue(ContractFileType.CriticalProjectDecisionRecord) + "未上传");
loseFile = true;
}
}
}
}
}
if (loseFile && files.isEmpty()) {
holder.warn("!上传文件空!");
}
return !loseFile;
}
}