调整 合同、运力、基础配置、客商
This commit is contained in:
+4
-1
@@ -136,7 +136,10 @@ public class DictBizServiceImpl extends ServiceImpl<DictBizMapper, DictBiz> impl
|
||||
|
||||
@Override
|
||||
public IPage<DictBizVO> parentList(Map<String, Object> dict, Query query) {
|
||||
IPage<DictBiz> page = this.page(Condition.getPage(query), Condition.getQueryWrapper(dict, DictBiz.class).lambda().eq(DictBiz::getParentId, CommonConstant.TOP_PARENT_ID).orderByAsc(DictBiz::getSort));
|
||||
IPage<DictBiz> page = this.page(Condition.getPage(query), Condition.getQueryWrapper(dict, DictBiz.class).lambda()
|
||||
.eq(DictBiz::getParentId, CommonConstant.TOP_PARENT_ID)
|
||||
.orderByAsc(DictBiz::getSort)
|
||||
.orderByDesc(DictBiz::getId));
|
||||
return DictBizWrapper.build().pageVO(page);
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -123,7 +123,10 @@ public class DictServiceImpl extends ServiceImpl<DictMapper, Dict> implements ID
|
||||
|
||||
@Override
|
||||
public IPage<DictVO> parentList(Map<String, Object> dict, Query query) {
|
||||
IPage<Dict> page = this.page(Condition.getPage(query), Condition.getQueryWrapper(dict, Dict.class).lambda().eq(Dict::getParentId, CommonConstant.TOP_PARENT_ID).orderByAsc(Dict::getSort));
|
||||
IPage<Dict> page = this.page(Condition.getPage(query), Condition.getQueryWrapper(dict, Dict.class).lambda()
|
||||
.eq(Dict::getParentId, CommonConstant.TOP_PARENT_ID)
|
||||
.orderByAsc(Dict::getSort)
|
||||
.orderByDesc(Dict::getId));
|
||||
return DictWrapper.build().pageVO(page);
|
||||
}
|
||||
|
||||
|
||||
+34
-3
@@ -47,6 +47,7 @@ import org.springblade.transport.excel.AnnualInspectionRecordExcel;
|
||||
import org.springblade.transport.excel.AnnualInspectionRecordExportExcel;
|
||||
import org.springblade.transport.excel.AnnualInspectionRecordImporter;
|
||||
import org.springblade.transport.pojo.entity.AnnualInspectionRecord;
|
||||
import org.springblade.transport.pojo.vo.AnnualInspectionRecordExpiryStatVO;
|
||||
import org.springblade.transport.pojo.vo.AnnualInspectionRecordVO;
|
||||
import org.springblade.transport.service.IAnnualInspectionRecordService;
|
||||
import org.springblade.transport.wrapper.AnnualInspectionRecordWrapper;
|
||||
@@ -58,6 +59,7 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -91,6 +93,7 @@ public class AnnualInspectionRecordController extends BladeController {
|
||||
@ApiOperationSupport(order = 2)
|
||||
@Operation(summary = "分页", description = "传入annualInspectionRecord")
|
||||
public R<IPage<AnnualInspectionRecordVO>> list(AnnualInspectionRecordVO annualInspectionRecord, Query query) {
|
||||
fillExpiryDate(annualInspectionRecord);
|
||||
IPage<AnnualInspectionRecordVO> pages = annualInspectionRecordService.selectAnnualInspectionRecordPage(Condition.getPage(normalizeQuery(query)), annualInspectionRecord);
|
||||
return R.data(pages);
|
||||
}
|
||||
@@ -109,8 +112,17 @@ public class AnnualInspectionRecordController extends BladeController {
|
||||
return R.status(annualInspectionRecordService.deleteLogic(Func.toLongList(ids)));
|
||||
}
|
||||
|
||||
@PostMapping("/import-annual-inspection-record")
|
||||
@GetMapping("/expiry-stat")
|
||||
@ApiOperationSupport(order = 5)
|
||||
@Operation(summary = "有效期统计", description = "传入annualInspectionRecord")
|
||||
public R<AnnualInspectionRecordExpiryStatVO> expiryStat(AnnualInspectionRecordVO annualInspectionRecord) {
|
||||
fillExpiryDate(annualInspectionRecord);
|
||||
annualInspectionRecord.setExpireStatus(null);
|
||||
return R.data(annualInspectionRecordService.expiryStat(annualInspectionRecord));
|
||||
}
|
||||
|
||||
@PostMapping("/import-annual-inspection-record")
|
||||
@ApiOperationSupport(order = 6)
|
||||
@Operation(summary = "导入年检记录", description = "传入excel")
|
||||
public R importAnnualInspectionRecord(MultipartFile file, HttpServletResponse response) {
|
||||
List<AnnualInspectionRecordExcel> failureList = annualInspectionRecordService.importAnnualInspectionRecord(ExcelUtil.read(file, AnnualInspectionRecordExcel.class));
|
||||
@@ -122,17 +134,18 @@ public class AnnualInspectionRecordController extends BladeController {
|
||||
}
|
||||
|
||||
@GetMapping("/export-annual-inspection-record")
|
||||
@ApiOperationSupport(order = 6)
|
||||
@ApiOperationSupport(order = 7)
|
||||
@Operation(summary = "导出年检记录")
|
||||
public void exportAnnualInspectionRecord(AnnualInspectionRecordVO annualInspectionRecord,
|
||||
@RequestParam(required = false) String ids,
|
||||
HttpServletResponse response) {
|
||||
fillExpiryDate(annualInspectionRecord);
|
||||
List<AnnualInspectionRecordExportExcel> list = annualInspectionRecordService.exportAnnualInspectionRecord(buildExportQuery(annualInspectionRecord, ids));
|
||||
ExcelUtil.export(response, "年检记录" + DateUtil.time(), "年检记录表", list, AnnualInspectionRecordExportExcel.class);
|
||||
}
|
||||
|
||||
@GetMapping("/export-template")
|
||||
@ApiOperationSupport(order = 7)
|
||||
@ApiOperationSupport(order = 8)
|
||||
@Operation(summary = "导出模板")
|
||||
public void exportTemplate(HttpServletResponse response) {
|
||||
List<AnnualInspectionRecordExcel> list = new ArrayList<>();
|
||||
@@ -155,6 +168,15 @@ public class AnnualInspectionRecordController extends BladeController {
|
||||
return query;
|
||||
}
|
||||
|
||||
private void fillExpiryDate(AnnualInspectionRecordVO annualInspectionRecord) {
|
||||
if (annualInspectionRecord.getToday() == null) {
|
||||
annualInspectionRecord.setToday(LocalDate.now());
|
||||
}
|
||||
if (annualInspectionRecord.getWarningDate() == null) {
|
||||
annualInspectionRecord.setWarningDate(annualInspectionRecord.getToday().plusDays(30));
|
||||
}
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<AnnualInspectionRecord> buildExportQuery(AnnualInspectionRecordVO annualInspectionRecord, String ids) {
|
||||
LambdaQueryWrapper<AnnualInspectionRecord> queryWrapper = Wrappers.<AnnualInspectionRecord>lambdaQuery()
|
||||
.eq(AnnualInspectionRecord::getIsDeleted, 0)
|
||||
@@ -183,6 +205,15 @@ public class AnnualInspectionRecordController extends BladeController {
|
||||
if (Func.isNotEmpty(annualInspectionRecord.getCreateTimeEnd())) {
|
||||
queryWrapper.le(AnnualInspectionRecord::getCreateTime, annualInspectionRecord.getCreateTimeEnd());
|
||||
}
|
||||
if ("within30".equals(annualInspectionRecord.getExpireStatus())) {
|
||||
queryWrapper.isNotNull(AnnualInspectionRecord::getValidUntilDate)
|
||||
.ge(AnnualInspectionRecord::getValidUntilDate, annualInspectionRecord.getToday())
|
||||
.le(AnnualInspectionRecord::getValidUntilDate, annualInspectionRecord.getWarningDate());
|
||||
}
|
||||
if ("expired".equals(annualInspectionRecord.getExpireStatus())) {
|
||||
queryWrapper.isNotNull(AnnualInspectionRecord::getValidUntilDate)
|
||||
.lt(AnnualInspectionRecord::getValidUntilDate, annualInspectionRecord.getToday());
|
||||
}
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
|
||||
+11
-1
@@ -27,7 +27,9 @@ package org.springblade.transport.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springblade.transport.pojo.entity.AnnualInspectionRecord;
|
||||
import org.springblade.transport.pojo.vo.AnnualInspectionRecordExpiryStatVO;
|
||||
import org.springblade.transport.pojo.vo.AnnualInspectionRecordVO;
|
||||
|
||||
import java.util.List;
|
||||
@@ -46,6 +48,14 @@ public interface AnnualInspectionRecordMapper extends BaseMapper<AnnualInspectio
|
||||
* @param annualInspectionRecord 查询参数
|
||||
* @return 年检记录分页
|
||||
*/
|
||||
List<AnnualInspectionRecordVO> selectAnnualInspectionRecordPage(IPage<AnnualInspectionRecordVO> page, AnnualInspectionRecordVO annualInspectionRecord);
|
||||
List<AnnualInspectionRecordVO> selectAnnualInspectionRecordPage(IPage<AnnualInspectionRecordVO> page, @Param("annualInspectionRecord") AnnualInspectionRecordVO annualInspectionRecord);
|
||||
|
||||
/**
|
||||
* 有效期统计
|
||||
*
|
||||
* @param annualInspectionRecord 查询参数
|
||||
* @return 统计结果
|
||||
*/
|
||||
AnnualInspectionRecordExpiryStatVO selectExpiryStat(@Param("annualInspectionRecord") AnnualInspectionRecordVO annualInspectionRecord);
|
||||
|
||||
}
|
||||
|
||||
+55
-23
@@ -26,6 +26,49 @@
|
||||
<result column="remark" property="remark"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="ExpiryWithin30Condition">
|
||||
valid_until_date IS NOT NULL
|
||||
AND valid_until_date >= #{annualInspectionRecord.today}
|
||||
AND valid_until_date <= #{annualInspectionRecord.warningDate}
|
||||
</sql>
|
||||
|
||||
<sql id="ExpiryExpiredCondition">
|
||||
valid_until_date IS NOT NULL
|
||||
AND valid_until_date < #{annualInspectionRecord.today}
|
||||
</sql>
|
||||
|
||||
<sql id="QueryCondition">
|
||||
is_deleted = 0
|
||||
<if test="annualInspectionRecord.createDept != null">
|
||||
AND create_dept = #{annualInspectionRecord.createDept}
|
||||
</if>
|
||||
<if test="annualInspectionRecord.vehicleType != null and annualInspectionRecord.vehicleType != ''">
|
||||
AND vehicle_type = #{annualInspectionRecord.vehicleType}
|
||||
</if>
|
||||
<if test="annualInspectionRecord.vehicleNo != null and annualInspectionRecord.vehicleNo != ''">
|
||||
<bind name="vehicleNoLike" value="'%' + annualInspectionRecord.vehicleNo + '%'"/>
|
||||
AND vehicle_no LIKE #{vehicleNoLike}
|
||||
</if>
|
||||
<if test="annualInspectionRecord.inspectionAssessmentDateStart != null">
|
||||
AND inspection_assessment_date >= #{annualInspectionRecord.inspectionAssessmentDateStart}
|
||||
</if>
|
||||
<if test="annualInspectionRecord.inspectionAssessmentDateEnd != null">
|
||||
AND inspection_assessment_date <= #{annualInspectionRecord.inspectionAssessmentDateEnd}
|
||||
</if>
|
||||
<if test="annualInspectionRecord.createTimeStart != null">
|
||||
AND create_time >= #{annualInspectionRecord.createTimeStart}
|
||||
</if>
|
||||
<if test="annualInspectionRecord.createTimeEnd != null">
|
||||
AND create_time <= #{annualInspectionRecord.createTimeEnd}
|
||||
</if>
|
||||
<if test="annualInspectionRecord.expireStatus != null and annualInspectionRecord.expireStatus == 'within30'">
|
||||
AND <include refid="ExpiryWithin30Condition"/>
|
||||
</if>
|
||||
<if test="annualInspectionRecord.expireStatus != null and annualInspectionRecord.expireStatus == 'expired'">
|
||||
AND <include refid="ExpiryExpiredCondition"/>
|
||||
</if>
|
||||
</sql>
|
||||
|
||||
<select id="selectAnnualInspectionRecordPage" resultMap="annualInspectionRecordResultMap">
|
||||
SELECT
|
||||
id,
|
||||
@@ -52,30 +95,19 @@
|
||||
FROM
|
||||
blade_annual_inspection_record
|
||||
WHERE
|
||||
is_deleted = 0
|
||||
<if test="annualInspectionRecord.createDept != null">
|
||||
AND create_dept = #{annualInspectionRecord.createDept}
|
||||
</if>
|
||||
<if test="annualInspectionRecord.vehicleType != null and annualInspectionRecord.vehicleType != ''">
|
||||
AND vehicle_type = #{annualInspectionRecord.vehicleType}
|
||||
</if>
|
||||
<if test="annualInspectionRecord.vehicleNo != null and annualInspectionRecord.vehicleNo != ''">
|
||||
<bind name="vehicleNoLike" value="'%' + annualInspectionRecord.vehicleNo + '%'"/>
|
||||
AND vehicle_no LIKE #{vehicleNoLike}
|
||||
</if>
|
||||
<if test="annualInspectionRecord.inspectionAssessmentDateStart != null">
|
||||
AND inspection_assessment_date >= #{annualInspectionRecord.inspectionAssessmentDateStart}
|
||||
</if>
|
||||
<if test="annualInspectionRecord.inspectionAssessmentDateEnd != null">
|
||||
AND inspection_assessment_date <= #{annualInspectionRecord.inspectionAssessmentDateEnd}
|
||||
</if>
|
||||
<if test="annualInspectionRecord.createTimeStart != null">
|
||||
AND create_time >= #{annualInspectionRecord.createTimeStart}
|
||||
</if>
|
||||
<if test="annualInspectionRecord.createTimeEnd != null">
|
||||
AND create_time <= #{annualInspectionRecord.createTimeEnd}
|
||||
</if>
|
||||
<include refid="QueryCondition"/>
|
||||
ORDER BY create_time DESC
|
||||
</select>
|
||||
|
||||
<select id="selectExpiryStat" resultType="org.springblade.transport.pojo.vo.AnnualInspectionRecordExpiryStatVO">
|
||||
SELECT
|
||||
COUNT(1) AS total,
|
||||
SUM(CASE WHEN <include refid="ExpiryWithin30Condition"/> THEN 1 ELSE 0 END) AS within30,
|
||||
SUM(CASE WHEN <include refid="ExpiryExpiredCondition"/> THEN 1 ELSE 0 END) AS expired
|
||||
FROM
|
||||
blade_annual_inspection_record
|
||||
WHERE
|
||||
<include refid="QueryCondition"/>
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
+4
@@ -16,6 +16,7 @@
|
||||
<result column="short_name" property="shortName"/>
|
||||
<result column="full_name" property="fullName"/>
|
||||
<result column="customer_nature" property="customerNature"/>
|
||||
<result column="guangxi_top100" property="guangxiTop100"/>
|
||||
<result column="unified_credit_code" property="unifiedCreditCode"/>
|
||||
<result column="customer_type" property="customerType"/>
|
||||
<result column="project_name" property="projectName"/>
|
||||
@@ -29,6 +30,7 @@
|
||||
<result column="dept_name" property="deptName"/>
|
||||
<result column="invoice_tax_rate" property="invoiceTaxRate"/>
|
||||
<result column="business_scope" property="businessScope"/>
|
||||
<result column="network_freight_platform" property="networkFreightPlatform"/>
|
||||
<result column="business_term_type" property="businessTermType"/>
|
||||
<result column="business_end_date" property="businessEndDate"/>
|
||||
<result column="registered_capital" property="registeredCapital"/>
|
||||
@@ -61,6 +63,7 @@
|
||||
short_name,
|
||||
full_name,
|
||||
customer_nature,
|
||||
guangxi_top100,
|
||||
unified_credit_code,
|
||||
customer_type,
|
||||
project_name,
|
||||
@@ -74,6 +77,7 @@
|
||||
dept_name,
|
||||
invoice_tax_rate,
|
||||
business_scope,
|
||||
network_freight_platform,
|
||||
business_term_type,
|
||||
business_end_date,
|
||||
registered_capital,
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.transport.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.springblade.transport.pojo.entity.CustomerInvoiceContact;
|
||||
|
||||
/**
|
||||
* 客商发票联系信息 Mapper 接口
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface CustomerInvoiceContactMapper extends BaseMapper<CustomerInvoiceContact> {
|
||||
}
|
||||
+3
@@ -31,6 +31,7 @@ import org.springblade.core.mp.base.BaseService;
|
||||
import org.springblade.transport.excel.AnnualInspectionRecordExcel;
|
||||
import org.springblade.transport.excel.AnnualInspectionRecordExportExcel;
|
||||
import org.springblade.transport.pojo.entity.AnnualInspectionRecord;
|
||||
import org.springblade.transport.pojo.vo.AnnualInspectionRecordExpiryStatVO;
|
||||
import org.springblade.transport.pojo.vo.AnnualInspectionRecordVO;
|
||||
|
||||
import java.util.List;
|
||||
@@ -44,6 +45,8 @@ public interface IAnnualInspectionRecordService extends BaseService<AnnualInspec
|
||||
|
||||
IPage<AnnualInspectionRecordVO> selectAnnualInspectionRecordPage(IPage<AnnualInspectionRecordVO> page, AnnualInspectionRecordVO annualInspectionRecord);
|
||||
|
||||
AnnualInspectionRecordExpiryStatVO expiryStat(AnnualInspectionRecordVO annualInspectionRecord);
|
||||
|
||||
boolean submit(AnnualInspectionRecord annualInspectionRecord);
|
||||
|
||||
List<AnnualInspectionRecordExcel> importAnnualInspectionRecord(List<AnnualInspectionRecordExcel> data);
|
||||
|
||||
+1
@@ -68,6 +68,7 @@ public interface ICustomerArchiveService extends BaseService<CustomerArchive> {
|
||||
|
||||
/**
|
||||
* 新增或修改客商档案
|
||||
* <p>仅当 {@code customer.recordChange = true}(前端点「提交」)时写入变更记录;「保存」不落变更记录。</p>
|
||||
*
|
||||
* @param customer 客商档案
|
||||
* @return 是否成功
|
||||
|
||||
+23
-4
@@ -36,13 +36,13 @@ import org.springblade.transport.excel.AnnualInspectionRecordExcel;
|
||||
import org.springblade.transport.excel.AnnualInspectionRecordExportExcel;
|
||||
import org.springblade.transport.mapper.AnnualInspectionRecordMapper;
|
||||
import org.springblade.transport.pojo.entity.AnnualInspectionRecord;
|
||||
import org.springblade.transport.pojo.vo.AnnualInspectionRecordExpiryStatVO;
|
||||
import org.springblade.transport.pojo.vo.AnnualInspectionRecordVO;
|
||||
import org.springblade.transport.service.IAnnualInspectionRecordService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@@ -74,6 +74,24 @@ public class AnnualInspectionRecordServiceImpl extends BaseServiceImpl<AnnualIns
|
||||
return page.setRecords(records);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnualInspectionRecordExpiryStatVO expiryStat(AnnualInspectionRecordVO annualInspectionRecord) {
|
||||
AnnualInspectionRecordExpiryStatVO stat = baseMapper.selectExpiryStat(annualInspectionRecord);
|
||||
if (stat == null) {
|
||||
stat = new AnnualInspectionRecordExpiryStatVO();
|
||||
}
|
||||
if (stat.getTotal() == null) {
|
||||
stat.setTotal(0L);
|
||||
}
|
||||
if (stat.getWithin30() == null) {
|
||||
stat.setWithin30(0L);
|
||||
}
|
||||
if (stat.getExpired() == null) {
|
||||
stat.setExpired(0L);
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean submit(AnnualInspectionRecord annualInspectionRecord) {
|
||||
@@ -131,6 +149,7 @@ public class AnnualInspectionRecordServiceImpl extends BaseServiceImpl<AnnualIns
|
||||
org.springblade.common.excel.ImportFailureExcelUtil.addValidationError(validationErrors, SHIP.equals(annualInspectionRecord.getVehicleType()) && Func.isEmpty(annualInspectionRecord.getShipInspectionType()), "船舶检验类型不能为空");
|
||||
org.springblade.common.excel.ImportFailureExcelUtil.addValidationError(validationErrors, Func.isNotEmpty(annualInspectionRecord.getPassengerTypeLevel()) && !PASSENGER_TYPE_LEVELS.contains(annualInspectionRecord.getPassengerTypeLevel()), "客车类型及等级不正确");
|
||||
org.springblade.common.excel.ImportFailureExcelUtil.addValidationError(validationErrors, Func.isEmpty(annualInspectionRecord.getValidUntilDate()), "有效期截止日不能为空");
|
||||
org.springblade.common.excel.ImportFailureExcelUtil.addValidationError(validationErrors, Func.isEmpty(annualInspectionRecord.getInspectionAssessmentDate()), "检测评定日期不能为空");
|
||||
org.springblade.common.excel.ImportFailureExcelUtil.addValidationError(validationErrors, Func.isNotEmpty(annualInspectionRecord.getValidUntilDate()) && Func.isNotEmpty(annualInspectionRecord.getInspectionAssessmentDate()) && !annualInspectionRecord.getValidUntilDate().isAfter(annualInspectionRecord.getInspectionAssessmentDate()), "有效期截止日应大于检测评定日期");
|
||||
org.springblade.common.excel.ImportFailureExcelUtil.addValidationError(validationErrors, Func.isEmpty(annualInspectionRecord.getFee()), "费用不能为空");
|
||||
org.springblade.common.excel.ImportFailureExcelUtil.addLengthValidationError(validationErrors, annualInspectionRecord.getVehicleNo(), VEHICLE_NO_MAX_LENGTH, "车牌号/船号不能超过30字");
|
||||
@@ -170,9 +189,6 @@ public class AnnualInspectionRecordServiceImpl extends BaseServiceImpl<AnnualIns
|
||||
annualInspectionRecord.setAssessmentUnit(trimToNull(annualInspectionRecord.getAssessmentUnit()));
|
||||
annualInspectionRecord.setAttachments(trimToNull(annualInspectionRecord.getAttachments()));
|
||||
annualInspectionRecord.setRemark(trimToNull(annualInspectionRecord.getRemark()));
|
||||
if (annualInspectionRecord.getInspectionAssessmentDate() == null) {
|
||||
annualInspectionRecord.setInspectionAssessmentDate(LocalDate.now());
|
||||
}
|
||||
if (VEHICLE.equals(annualInspectionRecord.getVehicleType())) {
|
||||
annualInspectionRecord.setShipInspectionType(null);
|
||||
} else {
|
||||
@@ -203,6 +219,9 @@ public class AnnualInspectionRecordServiceImpl extends BaseServiceImpl<AnnualIns
|
||||
if (Func.isEmpty(annualInspectionRecord.getValidUntilDate())) {
|
||||
throw new ServiceException("有效期截止日不能为空");
|
||||
}
|
||||
if (Func.isEmpty(annualInspectionRecord.getInspectionAssessmentDate())) {
|
||||
throw new ServiceException("检测评定日期不能为空");
|
||||
}
|
||||
if (!annualInspectionRecord.getValidUntilDate().isAfter(annualInspectionRecord.getInspectionAssessmentDate())) {
|
||||
throw new ServiceException("有效期截止日应大于检测评定日期");
|
||||
}
|
||||
|
||||
+30
-1
@@ -121,6 +121,16 @@ public class ContractManageServiceImpl extends BaseServiceImpl<ContractManageMap
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean submit(ContractManage contractManage) {
|
||||
// 变更驳回后从编辑页提交,应重新进入变更审批,不能走临时合同提交流程。
|
||||
if (Func.isNotEmpty(contractManage.getId())) {
|
||||
ContractManage existing = loadExists(contractManage.getId());
|
||||
if (Objects.equals(existing.getApprovalStatus(), STATUS_CHANGE_REJECTED)) {
|
||||
if (Func.isEmpty(TransportBusinessSupport.trimToNull(contractManage.getChangeReason()))) {
|
||||
contractManage.setChangeReason(resolveResubmitChangeReason(existing));
|
||||
}
|
||||
return submitChange(contractManage);
|
||||
}
|
||||
}
|
||||
prepare(contractManage);
|
||||
validateDraft(contractManage);
|
||||
validateTemporary(contractManage);
|
||||
@@ -262,6 +272,9 @@ public class ContractManageServiceImpl extends BaseServiceImpl<ContractManageMap
|
||||
}
|
||||
TransportBusinessSupport.validateRequired(request.getSettlementCurrency(), "请选择结算币种");
|
||||
String changeReason = TransportBusinessSupport.trimToNull(request.getChangeReason());
|
||||
if (Func.isEmpty(changeReason) && Objects.equals(source.getApprovalStatus(), STATUS_CHANGE_REJECTED)) {
|
||||
changeReason = resolveResubmitChangeReason(source);
|
||||
}
|
||||
TransportBusinessSupport.validateRequired(changeReason, "请输入变更原因");
|
||||
TransportBusinessSupport.validateLength(changeReason, 500, "变更原因不能超过500字");
|
||||
ContractManage candidate = new ContractManage();
|
||||
@@ -848,7 +861,8 @@ public class ContractManageServiceImpl extends BaseServiceImpl<ContractManageMap
|
||||
|
||||
private ContractManage loadEditable(Long id) {
|
||||
ContractManage contractManage = loadExists(id);
|
||||
if (!List.of(STATUS_DRAFT, STATUS_WITHDRAWN, STATUS_REJECTED).contains(contractManage.getApprovalStatus())) {
|
||||
if (!List.of(STATUS_DRAFT, STATUS_WITHDRAWN, STATUS_REJECTED, STATUS_CHANGE_REJECTED)
|
||||
.contains(contractManage.getApprovalStatus())) {
|
||||
throw new ServiceException("当前状态不允许编辑");
|
||||
}
|
||||
if (!canOperateInCurrentScope(contractManage)) {
|
||||
@@ -857,6 +871,21 @@ public class ContractManageServiceImpl extends BaseServiceImpl<ContractManageMap
|
||||
return contractManage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 变更驳回后重新提交时,优先沿用最近一次变更原因。
|
||||
*/
|
||||
private String resolveResubmitChangeReason(ContractManage contractManage) {
|
||||
List<Map<String, Object>> records = parseChangeRecords(contractManage.getChangeRecordJson());
|
||||
for (int index = records.size() - 1; index >= 0; index--) {
|
||||
String changeReason = TransportBusinessSupport.trimToNull(
|
||||
records.get(index).get("changeReason") == null ? null : String.valueOf(records.get(index).get("changeReason")));
|
||||
if (Func.isNotEmpty(changeReason)) {
|
||||
return changeReason;
|
||||
}
|
||||
}
|
||||
return "重新提交变更";
|
||||
}
|
||||
|
||||
private boolean canResubmitTemporary(ContractManage contractManage) {
|
||||
String stage = contractManage.getContractStage();
|
||||
String status = contractManage.getApprovalStatus();
|
||||
|
||||
+139
-14
@@ -46,6 +46,7 @@ import org.springblade.transport.mapper.CustomerChangeRecordMapper;
|
||||
import org.springblade.transport.mapper.CustomerContactMapper;
|
||||
import org.springblade.transport.mapper.CustomerCreditScoreDetailMapper;
|
||||
import org.springblade.transport.mapper.CustomerCreditScoreMapper;
|
||||
import org.springblade.transport.mapper.CustomerInvoiceContactMapper;
|
||||
import org.springblade.transport.mapper.CustomerInvoiceInfoMapper;
|
||||
import org.springblade.transport.mapper.CustomerReceiptAccountMapper;
|
||||
import org.springblade.transport.mapper.UserCustomerScopeMapper;
|
||||
@@ -59,6 +60,7 @@ import org.springblade.transport.pojo.entity.CustomerChangeRecord;
|
||||
import org.springblade.transport.pojo.entity.CustomerContact;
|
||||
import org.springblade.transport.pojo.entity.CustomerCreditScore;
|
||||
import org.springblade.transport.pojo.entity.CustomerCreditScoreDetail;
|
||||
import org.springblade.transport.pojo.entity.CustomerInvoiceContact;
|
||||
import org.springblade.transport.pojo.entity.CustomerInvoiceInfo;
|
||||
import org.springblade.transport.pojo.entity.CustomerReceiptAccount;
|
||||
import org.springblade.transport.pojo.vo.CustomerArchiveVO;
|
||||
@@ -67,6 +69,7 @@ import org.springblade.transport.pojo.vo.CustomerContactVO;
|
||||
import org.springblade.transport.pojo.vo.CustomerCreditScoreDetailVO;
|
||||
import org.springblade.transport.pojo.vo.CustomerCreditScoreVO;
|
||||
import org.springblade.transport.pojo.vo.CreditRatingStandardVO;
|
||||
import org.springblade.transport.pojo.vo.CustomerInvoiceContactVO;
|
||||
import org.springblade.transport.pojo.vo.CustomerInvoiceInfoVO;
|
||||
import org.springblade.transport.pojo.vo.CustomerReceiptAccountVO;
|
||||
import org.springblade.transport.service.ICustomerArchiveService;
|
||||
@@ -108,6 +111,7 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
||||
private final CustomerContactMapper contactMapper;
|
||||
private final CustomerReceiptAccountMapper receiptAccountMapper;
|
||||
private final CustomerInvoiceInfoMapper invoiceInfoMapper;
|
||||
private final CustomerInvoiceContactMapper invoiceContactMapper;
|
||||
private final CustomerCreditScoreMapper creditScoreMapper;
|
||||
private final CustomerCreditScoreDetailMapper creditScoreDetailMapper;
|
||||
private final CustomerChangeRecordMapper changeRecordMapper;
|
||||
@@ -173,7 +177,8 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
||||
if (created && result) {
|
||||
grantNewCustomerToIncludedUsers(entity);
|
||||
}
|
||||
if (result && !created) {
|
||||
// 仅「提交」写入变更记录;「保存」不落变更记录
|
||||
if (result && !created && Boolean.TRUE.equals(customer.getRecordChange())) {
|
||||
addChangeRecord(entity.getId(), "修改客商档案", before, entity, beforeDetail, customer);
|
||||
}
|
||||
return result;
|
||||
@@ -292,6 +297,7 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
||||
customer.setShortName(trimToNull(customer.getShortName()));
|
||||
customer.setFullName(trimToEmpty(customer.getFullName()));
|
||||
customer.setCustomerNature(trimToEmpty(customer.getCustomerNature()));
|
||||
customer.setGuangxiTop100(normalizeYesNoFlag(customer.getGuangxiTop100()));
|
||||
customer.setUnifiedCreditCode(trimToEmpty(customer.getUnifiedCreditCode()));
|
||||
customer.setCustomerType(trimToEmpty(customer.getCustomerType()));
|
||||
customer.setBusinessScope(trimToNull(customer.getBusinessScope()));
|
||||
@@ -428,7 +434,7 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
||||
deleteDetail(List.of(customerId), false);
|
||||
insertContacts(customerId, customer.getContacts());
|
||||
insertReceiptAccounts(customerId, customer.getReceiptAccounts());
|
||||
insertInvoices(customerId, customer.getInvoices());
|
||||
insertInvoices(customerId, customer);
|
||||
if (Func.isNotEmpty(customer.getScores())) {
|
||||
deleteScores(List.of(customerId));
|
||||
insertScores(customerId, customer.getScores());
|
||||
@@ -461,27 +467,111 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
||||
}
|
||||
}
|
||||
|
||||
private void insertInvoices(Long customerId, List<CustomerInvoiceInfoVO> invoices) {
|
||||
private void insertInvoices(Long customerId, CustomerArchiveVO customer) {
|
||||
List<CustomerInvoiceInfoVO> invoices = customer.getInvoices();
|
||||
if (Func.isEmpty(invoices)) {
|
||||
return;
|
||||
}
|
||||
boolean internal = isInternalCustomer(customer);
|
||||
for (CustomerInvoiceInfoVO invoiceVO : invoices) {
|
||||
if (Func.isEmpty(invoiceVO.getInvoiceTitle()) && Func.isEmpty(invoiceVO.getTaxNo())) {
|
||||
continue;
|
||||
}
|
||||
if (Func.isEmpty(invoiceVO.getInvoiceType())) {
|
||||
throw new ServiceException("发票类型不能为空");
|
||||
if (Func.isEmpty(invoiceVO.getInvoiceTitle())) {
|
||||
throw new ServiceException("企业全称不能为空");
|
||||
}
|
||||
if (!List.of("增值税专用发票", "普通发票").contains(invoiceVO.getInvoiceType())) {
|
||||
throw new ServiceException("发票类型不合法");
|
||||
if (Func.isEmpty(invoiceVO.getTaxNo())) {
|
||||
throw new ServiceException("纳税人识别号不能为空");
|
||||
}
|
||||
if (Func.isEmpty(invoiceVO.getBankName())) {
|
||||
throw new ServiceException("开户行名称不能为空");
|
||||
}
|
||||
if (Func.isEmpty(invoiceVO.getBankAccount())) {
|
||||
throw new ServiceException("银行账号不能为空");
|
||||
}
|
||||
if (Func.isEmpty(invoiceVO.getRegisteredRegionName()) && Func.isEmpty(invoiceVO.getRegisteredAddress())) {
|
||||
throw new ServiceException("注册地址不能为空");
|
||||
}
|
||||
if (Func.isEmpty(invoiceVO.getRegisteredDetailAddress())) {
|
||||
throw new ServiceException("详细地址不能为空");
|
||||
}
|
||||
invoiceVO.setRegisteredAddress(buildAddress(invoiceVO.getRegisteredRegionName(), invoiceVO.getRegisteredDetailAddress(), invoiceVO.getRegisteredAddress()));
|
||||
invoiceVO.setReceiverAddress(buildAddress(invoiceVO.getReceiverRegionName(), invoiceVO.getReceiverDetailAddress(), invoiceVO.getReceiverAddress()));
|
||||
CustomerInvoiceInfo invoice = Objects.requireNonNull(BeanUtil.copyProperties(invoiceVO, CustomerInvoiceInfo.class));
|
||||
invoice.setId(IdWorker.getId());
|
||||
invoice.setCustomerId(customerId);
|
||||
invoice.setStatus(STATUS_ENABLED);
|
||||
invoiceInfoMapper.insert(invoice);
|
||||
insertInvoiceContacts(invoice.getId(), invoiceVO.getContacts(), internal, customer);
|
||||
}
|
||||
}
|
||||
|
||||
private void insertInvoiceContacts(Long invoiceId, List<CustomerInvoiceContactVO> contacts, boolean internal,
|
||||
CustomerArchiveVO customer) {
|
||||
if (Func.isEmpty(contacts)) {
|
||||
return;
|
||||
}
|
||||
for (CustomerInvoiceContactVO contactVO : contacts) {
|
||||
if (isBlankInvoiceContact(contactVO)) {
|
||||
continue;
|
||||
}
|
||||
if (Func.isEmpty(contactVO.getContactName())) {
|
||||
throw new ServiceException("发票联系人不能为空");
|
||||
}
|
||||
if (Func.isEmpty(contactVO.getContactPhone())) {
|
||||
throw new ServiceException("发票联系电话不能为空");
|
||||
}
|
||||
validateInvoiceContactEmail(contactVO.getEmail());
|
||||
if (Func.isNotEmpty(contactVO.getRemark()) && contactVO.getRemark().length() > 200) {
|
||||
throw new ServiceException("发票联系信息备注最多200个字");
|
||||
}
|
||||
if (internal && Func.isEmpty(contactVO.getDeptIds()) && Func.isEmpty(contactVO.getDeptNames())) {
|
||||
throw new ServiceException("内部组织客商必须选择发票联系信息所属部门");
|
||||
}
|
||||
if (!internal) {
|
||||
if (Func.isEmpty(contactVO.getDeptIds())) {
|
||||
contactVO.setDeptIds(customer.getDeptIds());
|
||||
}
|
||||
if (Func.isEmpty(contactVO.getDeptNames())) {
|
||||
contactVO.setDeptNames(Func.isNotEmpty(customer.getFullName()) ? customer.getFullName() : customer.getDeptName());
|
||||
}
|
||||
}
|
||||
CustomerInvoiceContact contact = Objects.requireNonNull(BeanUtil.copyProperties(contactVO, CustomerInvoiceContact.class));
|
||||
contact.setId(IdWorker.getId());
|
||||
contact.setInvoiceId(invoiceId);
|
||||
contact.setStatus(STATUS_ENABLED);
|
||||
invoiceContactMapper.insert(contact);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isBlankInvoiceContact(CustomerInvoiceContactVO contactVO) {
|
||||
return Func.isEmpty(contactVO.getContactName())
|
||||
&& Func.isEmpty(contactVO.getContactPhone())
|
||||
&& Func.isEmpty(contactVO.getEmail())
|
||||
&& Func.isEmpty(contactVO.getDeptIds())
|
||||
&& Func.isEmpty(contactVO.getDeptNames())
|
||||
&& Func.isEmpty(contactVO.getRemark());
|
||||
}
|
||||
|
||||
private void validateInvoiceContactEmail(String email) {
|
||||
if (Func.isEmpty(email)) {
|
||||
return;
|
||||
}
|
||||
if (email.length() > 100) {
|
||||
throw new ServiceException("发票联系邮箱不能超过100个字");
|
||||
}
|
||||
if (!email.matches("^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$")) {
|
||||
throw new ServiceException("发票联系邮箱格式不正确");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isInternalCustomer(CustomerArchiveVO customer) {
|
||||
String customerKind = customer.getCustomerKind();
|
||||
if (Func.isNotEmpty(customerKind)) {
|
||||
return "internal".equals(customerKind) || "内部组织".equals(customerKind);
|
||||
}
|
||||
return "internal".equals(customer.getCustomerNature()) || "内部组织".equals(customer.getCustomerNature());
|
||||
}
|
||||
|
||||
private void insertScores(Long customerId, List<CustomerCreditScoreVO> scores) {
|
||||
for (CustomerCreditScoreVO scoreVO : scores) {
|
||||
if (Func.isEmpty(scoreVO.getQuantificationId()) && Func.isEmpty(scoreVO.getScoreDate())) {
|
||||
@@ -529,6 +619,15 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
||||
private void deleteDetail(List<Long> customerIds, boolean deleteScores) {
|
||||
contactMapper.update(null, Wrappers.<CustomerContact>lambdaUpdate().in(CustomerContact::getCustomerId, customerIds).set(CustomerContact::getIsDeleted, 1));
|
||||
receiptAccountMapper.update(null, Wrappers.<CustomerReceiptAccount>lambdaUpdate().in(CustomerReceiptAccount::getCustomerId, customerIds).set(CustomerReceiptAccount::getIsDeleted, 1));
|
||||
List<CustomerInvoiceInfo> invoices = invoiceInfoMapper.selectList(Wrappers.<CustomerInvoiceInfo>lambdaQuery()
|
||||
.in(CustomerInvoiceInfo::getCustomerId, customerIds)
|
||||
.eq(CustomerInvoiceInfo::getIsDeleted, 0));
|
||||
if (Func.isNotEmpty(invoices)) {
|
||||
List<Long> invoiceIds = invoices.stream().map(CustomerInvoiceInfo::getId).toList();
|
||||
invoiceContactMapper.update(null, Wrappers.<CustomerInvoiceContact>lambdaUpdate()
|
||||
.in(CustomerInvoiceContact::getInvoiceId, invoiceIds)
|
||||
.set(CustomerInvoiceContact::getIsDeleted, 1));
|
||||
}
|
||||
invoiceInfoMapper.update(null, Wrappers.<CustomerInvoiceInfo>lambdaUpdate().in(CustomerInvoiceInfo::getCustomerId, customerIds).set(CustomerInvoiceInfo::getIsDeleted, 1));
|
||||
if (deleteScores) {
|
||||
deleteScores(customerIds);
|
||||
@@ -565,12 +664,27 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
||||
}
|
||||
|
||||
private List<CustomerInvoiceInfoVO> loadInvoices(Long customerId) {
|
||||
return invoiceInfoMapper.selectList(Wrappers.<CustomerInvoiceInfo>lambdaQuery()
|
||||
.eq(CustomerInvoiceInfo::getCustomerId, customerId)
|
||||
.eq(CustomerInvoiceInfo::getIsDeleted, 0)
|
||||
.orderByDesc(CustomerInvoiceInfo::getIsDefault)
|
||||
.orderByAsc(CustomerInvoiceInfo::getCreateTime))
|
||||
.stream().map(invoice -> Objects.requireNonNull(BeanUtil.copyProperties(invoice, CustomerInvoiceInfoVO.class))).toList();
|
||||
List<CustomerInvoiceInfo> invoices = invoiceInfoMapper.selectList(Wrappers.<CustomerInvoiceInfo>lambdaQuery()
|
||||
.eq(CustomerInvoiceInfo::getCustomerId, customerId)
|
||||
.eq(CustomerInvoiceInfo::getIsDeleted, 0)
|
||||
.orderByDesc(CustomerInvoiceInfo::getIsDefault)
|
||||
.orderByAsc(CustomerInvoiceInfo::getCreateTime));
|
||||
if (Func.isEmpty(invoices)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<Long> invoiceIds = invoices.stream().map(CustomerInvoiceInfo::getId).toList();
|
||||
Map<Long, List<CustomerInvoiceContactVO>> contactMap = invoiceContactMapper.selectList(Wrappers.<CustomerInvoiceContact>lambdaQuery()
|
||||
.in(CustomerInvoiceContact::getInvoiceId, invoiceIds)
|
||||
.eq(CustomerInvoiceContact::getIsDeleted, 0)
|
||||
.orderByAsc(CustomerInvoiceContact::getCreateTime))
|
||||
.stream()
|
||||
.map(contact -> Objects.requireNonNull(BeanUtil.copyProperties(contact, CustomerInvoiceContactVO.class)))
|
||||
.collect(Collectors.groupingBy(CustomerInvoiceContactVO::getInvoiceId));
|
||||
return invoices.stream().map(invoice -> {
|
||||
CustomerInvoiceInfoVO invoiceVO = Objects.requireNonNull(BeanUtil.copyProperties(invoice, CustomerInvoiceInfoVO.class));
|
||||
invoiceVO.setContacts(contactMap.getOrDefault(invoice.getId(), new ArrayList<>()));
|
||||
return invoiceVO;
|
||||
}).toList();
|
||||
}
|
||||
|
||||
private List<CustomerCreditScoreVO> loadScores(Long customerId) {
|
||||
@@ -621,6 +735,16 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
||||
return value != null && value.compareTo(BigDecimal.ONE.negate()) == 0 ? null : value;
|
||||
}
|
||||
|
||||
private Integer normalizeYesNoFlag(Integer value) {
|
||||
if (value == null || Objects.equals(value, -1)) {
|
||||
return null;
|
||||
}
|
||||
if (value == 0 || value == 1) {
|
||||
return value;
|
||||
}
|
||||
throw new ServiceException("是否广西百强只能选择是或否");
|
||||
}
|
||||
|
||||
private Object parseScoreAttachments(String value) {
|
||||
if (Func.isEmpty(value)) {
|
||||
return new ArrayList<>();
|
||||
@@ -928,6 +1052,7 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
||||
snapshot.put("客商简称", customer.getShortName());
|
||||
snapshot.put("客商全称", customer.getFullName());
|
||||
snapshot.put("客商性质", customer.getCustomerNature());
|
||||
snapshot.put("是否广西百强", customer.getGuangxiTop100());
|
||||
snapshot.put("统一社会信用代码", customer.getUnifiedCreditCode());
|
||||
snapshot.put("客商类型", customer.getCustomerType());
|
||||
snapshot.put("所属项目", customer.getProjectName());
|
||||
|
||||
+9
@@ -55,6 +55,7 @@ public class InsuranceOcrTemplateServiceImpl extends BaseServiceImpl<InsuranceOc
|
||||
|
||||
private static final int NAME_MAX_LENGTH = 100;
|
||||
private static final int MAPPING_VALUE_MAX_LENGTH = 100;
|
||||
private static final List<String> VEHICLE_TYPES = List.of("车辆", "船舶");
|
||||
private static final List<String> INSURANCE_FIELD_KEYS = List.of(
|
||||
"保险类型", "保单号", "开始日期", "结束日期", "保额", "保费", "发票号", "开票日期", "备注"
|
||||
);
|
||||
@@ -64,6 +65,7 @@ public class InsuranceOcrTemplateServiceImpl extends BaseServiceImpl<InsuranceOc
|
||||
LambdaQueryWrapper<InsuranceOcrTemplate> queryWrapper = Wrappers.<InsuranceOcrTemplate>lambdaQuery()
|
||||
.eq(InsuranceOcrTemplate::getIsDeleted, 0)
|
||||
.like(StringUtil.isNotBlank(insuranceOcrTemplate.getName()), InsuranceOcrTemplate::getName, insuranceOcrTemplate.getName())
|
||||
.eq(StringUtil.isNotBlank(insuranceOcrTemplate.getVehicleType()), InsuranceOcrTemplate::getVehicleType, insuranceOcrTemplate.getVehicleType())
|
||||
.orderByDesc(InsuranceOcrTemplate::getCreateTime);
|
||||
return InsuranceOcrTemplateWrapper.build().pageVO(page(page, queryWrapper));
|
||||
}
|
||||
@@ -79,6 +81,7 @@ public class InsuranceOcrTemplateServiceImpl extends BaseServiceImpl<InsuranceOc
|
||||
insuranceOcrTemplate.setTenantId(oldTemplate.getTenantId());
|
||||
}
|
||||
insuranceOcrTemplate.setName(trimToNull(insuranceOcrTemplate.getName()));
|
||||
insuranceOcrTemplate.setVehicleType(trimToNull(insuranceOcrTemplate.getVehicleType()));
|
||||
insuranceOcrTemplate.setMappingConfig(trimToNull(insuranceOcrTemplate.getMappingConfig()));
|
||||
if (created && insuranceOcrTemplate.getStatus() == null) {
|
||||
insuranceOcrTemplate.setStatus(1);
|
||||
@@ -94,6 +97,12 @@ public class InsuranceOcrTemplateServiceImpl extends BaseServiceImpl<InsuranceOc
|
||||
if (insuranceOcrTemplate.getName().length() > NAME_MAX_LENGTH) {
|
||||
throw new ServiceException("模板名称不能超过100个字符");
|
||||
}
|
||||
if (StringUtil.isBlank(insuranceOcrTemplate.getVehicleType())) {
|
||||
throw new ServiceException("请选择车船类型");
|
||||
}
|
||||
if (!VEHICLE_TYPES.contains(insuranceOcrTemplate.getVehicleType())) {
|
||||
throw new ServiceException("车船类型仅支持车辆或船舶");
|
||||
}
|
||||
Long nameCount = count(Wrappers.<InsuranceOcrTemplate>lambdaQuery()
|
||||
.eq(InsuranceOcrTemplate::getIsDeleted, 0)
|
||||
.eq(InsuranceOcrTemplate::getName, insuranceOcrTemplate.getName())
|
||||
|
||||
+9
@@ -85,6 +85,7 @@ public class InsuranceRecordServiceImpl extends BaseServiceImpl<InsuranceRecordM
|
||||
private static final Set<String> INSURANCE_TYPES = Set.of("交强险", "商业险", "承运人责任险", "货运险", "船舶险");
|
||||
private static final Set<String> SUPPORT_FILE_TYPES = Set.of("jpg", "jpeg", "png", "bmp");
|
||||
private static final Pattern DATE_PATTERN = Pattern.compile("(\\d{4})[-/.年](\\d{1,2})[-/.月](\\d{1,2})日?");
|
||||
private static final Pattern POLICY_NO_PATTERN = Pattern.compile("^[a-zA-Z0-9]+$");
|
||||
|
||||
private final IBaiduOcrService baiduOcrService;
|
||||
private final IInsuranceOcrTemplateService insuranceOcrTemplateService;
|
||||
@@ -157,6 +158,11 @@ public class InsuranceRecordServiceImpl extends BaseServiceImpl<InsuranceRecordM
|
||||
org.springblade.common.excel.ImportFailureExcelUtil.addValidationError(validationErrors, Func.isEmpty(insuranceRecord.getInsuranceType()), "保险类型不能为空");
|
||||
org.springblade.common.excel.ImportFailureExcelUtil.addValidationError(validationErrors, Func.isNotEmpty(insuranceRecord.getInsuranceType()) && !INSURANCE_TYPES.contains(insuranceRecord.getInsuranceType()), "保险类型不正确");
|
||||
org.springblade.common.excel.ImportFailureExcelUtil.addValidationError(validationErrors, Func.isEmpty(insuranceRecord.getPolicyNo()), "保单号不能为空");
|
||||
org.springblade.common.excel.ImportFailureExcelUtil.addValidationError(
|
||||
validationErrors,
|
||||
Func.isNotEmpty(insuranceRecord.getPolicyNo()) && !POLICY_NO_PATTERN.matcher(insuranceRecord.getPolicyNo()).matches(),
|
||||
"保单号只能输入数字、字母"
|
||||
);
|
||||
org.springblade.common.excel.ImportFailureExcelUtil.addValidationError(validationErrors, Func.isEmpty(insuranceRecord.getStartDate()), "开始日期不能为空");
|
||||
org.springblade.common.excel.ImportFailureExcelUtil.addValidationError(validationErrors, Func.isEmpty(insuranceRecord.getEndDate()), "结束日期不能为空");
|
||||
org.springblade.common.excel.ImportFailureExcelUtil.addValidationError(validationErrors, Func.isNotEmpty(insuranceRecord.getStartDate()) && Func.isNotEmpty(insuranceRecord.getEndDate()) && insuranceRecord.getEndDate().isBefore(insuranceRecord.getStartDate()), "结束日期不能早于开始日期");
|
||||
@@ -348,6 +354,9 @@ public class InsuranceRecordServiceImpl extends BaseServiceImpl<InsuranceRecordM
|
||||
if (Func.isEmpty(insuranceRecord.getPolicyNo())) {
|
||||
throw new ServiceException("保单号不能为空");
|
||||
}
|
||||
if (!POLICY_NO_PATTERN.matcher(insuranceRecord.getPolicyNo()).matches()) {
|
||||
throw new ServiceException("保单号只能输入数字、字母");
|
||||
}
|
||||
if (Func.isEmpty(insuranceRecord.getStartDate())) {
|
||||
throw new ServiceException("开始日期不能为空");
|
||||
}
|
||||
|
||||
+36
-6
@@ -37,6 +37,7 @@ import org.springblade.core.tool.utils.BeanUtil;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.transport.mapper.CustomerArchiveMapper;
|
||||
import org.springblade.transport.mapper.CustomerContactMapper;
|
||||
import org.springblade.transport.mapper.CustomerInvoiceContactMapper;
|
||||
import org.springblade.transport.mapper.CustomerInvoiceInfoMapper;
|
||||
import org.springblade.transport.mapper.ContractManageMapper;
|
||||
import org.springblade.transport.mapper.FormalSettlementDetailMapper;
|
||||
@@ -52,6 +53,7 @@ import org.springblade.transport.pojo.dto.InvoiceApplicationSaveRequest;
|
||||
import org.springblade.transport.pojo.dto.InvoiceApplicationStatusRequest;
|
||||
import org.springblade.transport.pojo.entity.CustomerArchive;
|
||||
import org.springblade.transport.pojo.entity.CustomerContact;
|
||||
import org.springblade.transport.pojo.entity.CustomerInvoiceContact;
|
||||
import org.springblade.transport.pojo.entity.CustomerInvoiceInfo;
|
||||
import org.springblade.transport.pojo.entity.ContractManage;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlement;
|
||||
@@ -63,6 +65,8 @@ import org.springblade.transport.pojo.entity.InvoiceApplicationRecord;
|
||||
import org.springblade.transport.pojo.entity.InvoiceApplicationSettlement;
|
||||
import org.springblade.transport.pojo.entity.InvoiceApplicationSheet;
|
||||
import org.springblade.transport.pojo.entity.Waybill;
|
||||
import org.springblade.transport.pojo.vo.CustomerInvoiceContactVO;
|
||||
import org.springblade.transport.pojo.vo.CustomerInvoiceInfoVO;
|
||||
import org.springblade.transport.pojo.vo.InvoiceApplicationSheetVO;
|
||||
import org.springblade.transport.pojo.vo.InvoiceApplicationVO;
|
||||
import org.springblade.transport.service.IInvoiceApplicationService;
|
||||
@@ -75,6 +79,7 @@ import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
@@ -111,6 +116,7 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl<InvoiceApplic
|
||||
private final ContractManageMapper contractManageMapper;
|
||||
private final CustomerArchiveMapper customerArchiveMapper;
|
||||
private final CustomerInvoiceInfoMapper customerInvoiceInfoMapper;
|
||||
private final CustomerInvoiceContactMapper customerInvoiceContactMapper;
|
||||
private final CustomerContactMapper customerContactMapper;
|
||||
|
||||
@Override
|
||||
@@ -267,7 +273,7 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl<InvoiceApplic
|
||||
String customerName = "receivable".equals(first.getSettlementType())
|
||||
? first.getPayerName() : first.getPayeeName();
|
||||
CustomerArchive customer = findCustomer(customerName);
|
||||
List<CustomerInvoiceInfo> invoiceInfos = customer == null ? List.of() : activeInvoiceInfos(customer.getId());
|
||||
List<CustomerInvoiceInfoVO> invoiceInfos = customer == null ? List.of() : activeInvoiceInfoVOs(customer.getId());
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
result.put("issuerName", first.getPayeeName());
|
||||
result.put("receiverName", first.getPayerName());
|
||||
@@ -321,8 +327,8 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl<InvoiceApplic
|
||||
}
|
||||
CustomerArchive customer = findCustomer(first.getPayerName());
|
||||
if (customer == null) throw new ServiceException("未找到正式结算单受票方对应的客商档案");
|
||||
List<CustomerInvoiceInfo> invoiceInfos = activeInvoiceInfos(customer.getId());
|
||||
CustomerInvoiceInfo invoiceInfo = invoiceInfos.stream()
|
||||
List<CustomerInvoiceInfoVO> invoiceInfos = activeInvoiceInfoVOs(customer.getId());
|
||||
CustomerInvoiceInfoVO invoiceInfo = invoiceInfos.stream()
|
||||
.filter(item -> Objects.equals(item.getId(), request.getReceiverInvoiceInfoId()))
|
||||
.findFirst().orElseThrow(() -> new ServiceException("请选择受票方有效的开票信息"));
|
||||
String departmentEmails = normalizeDepartmentEmails(request.getDepartmentEmails(), invoiceInfos);
|
||||
@@ -655,8 +661,32 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl<InvoiceApplic
|
||||
.orderByAsc(CustomerInvoiceInfo::getCreateTime));
|
||||
}
|
||||
|
||||
private List<String> invoiceInfoEmails(List<CustomerInvoiceInfo> invoiceInfos) {
|
||||
return invoiceInfos.stream().map(CustomerInvoiceInfo::getEmail).filter(Func::isNotEmpty)
|
||||
private List<CustomerInvoiceInfoVO> activeInvoiceInfoVOs(Long customerId) {
|
||||
List<CustomerInvoiceInfo> invoiceInfos = activeInvoiceInfos(customerId);
|
||||
if (Func.isEmpty(invoiceInfos)) {
|
||||
return List.of();
|
||||
}
|
||||
List<Long> invoiceIds = invoiceInfos.stream().map(CustomerInvoiceInfo::getId).toList();
|
||||
Map<Long, List<CustomerInvoiceContactVO>> contactMap = customerInvoiceContactMapper.selectList(
|
||||
Wrappers.<CustomerInvoiceContact>lambdaQuery()
|
||||
.in(CustomerInvoiceContact::getInvoiceId, invoiceIds)
|
||||
.eq(CustomerInvoiceContact::getIsDeleted, 0)
|
||||
.orderByAsc(CustomerInvoiceContact::getCreateTime))
|
||||
.stream()
|
||||
.map(contact -> Objects.requireNonNull(BeanUtil.copyProperties(contact, CustomerInvoiceContactVO.class)))
|
||||
.collect(Collectors.groupingBy(CustomerInvoiceContactVO::getInvoiceId));
|
||||
return invoiceInfos.stream().map(invoice -> {
|
||||
CustomerInvoiceInfoVO invoiceVO = Objects.requireNonNull(BeanUtil.copyProperties(invoice, CustomerInvoiceInfoVO.class));
|
||||
invoiceVO.setContacts(contactMap.getOrDefault(invoice.getId(), new ArrayList<>()));
|
||||
return invoiceVO;
|
||||
}).toList();
|
||||
}
|
||||
|
||||
private List<String> invoiceInfoEmails(List<CustomerInvoiceInfoVO> invoiceInfos) {
|
||||
return invoiceInfos.stream()
|
||||
.flatMap(invoice -> (invoice.getContacts() == null ? List.<CustomerInvoiceContactVO>of() : invoice.getContacts()).stream())
|
||||
.map(CustomerInvoiceContactVO::getEmail)
|
||||
.filter(Func::isNotEmpty)
|
||||
.flatMap(value -> splitEmails(value).stream())
|
||||
.collect(Collectors.toMap(email -> email.toLowerCase(Locale.ROOT), Function.identity(),
|
||||
(first, duplicate) -> first, LinkedHashMap::new)).values().stream().toList();
|
||||
@@ -708,7 +738,7 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl<InvoiceApplic
|
||||
.likeRight(InvoiceApplication::getApplicationNo, prefix)) + 1);
|
||||
}
|
||||
|
||||
private String normalizeDepartmentEmails(String value, List<CustomerInvoiceInfo> invoiceInfos) {
|
||||
private String normalizeDepartmentEmails(String value, List<CustomerInvoiceInfoVO> invoiceInfos) {
|
||||
Map<String, String> configuredEmails = invoiceInfoEmails(invoiceInfos).stream()
|
||||
.collect(Collectors.toMap(email -> email.toLowerCase(Locale.ROOT), Function.identity(),
|
||||
(first, duplicate) -> first, LinkedHashMap::new));
|
||||
|
||||
+19
-3
@@ -12,7 +12,9 @@ import org.springblade.core.log.exception.ServiceException;
|
||||
import org.springblade.core.mp.base.BaseServiceImpl;
|
||||
import org.springblade.core.tool.utils.BeanUtil;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.system.cache.DictBizCache;
|
||||
import org.springblade.system.cache.UserCache;
|
||||
import org.springblade.system.pojo.entity.DictBiz;
|
||||
import org.springblade.transport.excel.OtherExpenseRecordExcel;
|
||||
import org.springblade.transport.excel.OtherExpenseRecordExportExcel;
|
||||
import org.springblade.transport.mapper.OtherExpenseRecordMapper;
|
||||
@@ -28,6 +30,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 其他费用记录 服务实现类
|
||||
@@ -43,7 +46,7 @@ public class OtherExpenseRecordServiceImpl extends BaseServiceImpl<OtherExpenseR
|
||||
private static final int MONEY_SCALE = 2;
|
||||
private static final String VEHICLE = "车辆";
|
||||
private static final String SHIP = "船舶";
|
||||
private static final Set<String> EXPENSE_TYPES = Set.of("过路费", "停车费", "维修费", "保险费", "年检费", "装卸费", "其他");
|
||||
private static final String EXPENSE_TYPE_DICT_CODE = "other_fee_category";
|
||||
|
||||
@Override
|
||||
public IPage<OtherExpenseRecordVO> selectOtherExpenseRecordPage(IPage<OtherExpenseRecordVO> page, OtherExpenseRecordVO otherExpenseRecord) {
|
||||
@@ -103,7 +106,7 @@ public class OtherExpenseRecordServiceImpl extends BaseServiceImpl<OtherExpenseR
|
||||
List<String> validationErrors = new ArrayList<>();
|
||||
org.springblade.common.excel.ImportFailureExcelUtil.addValidationError(validationErrors, Func.isEmpty(otherExpenseRecord.getExpenseDate()), "费用日期不能为空");
|
||||
org.springblade.common.excel.ImportFailureExcelUtil.addValidationError(validationErrors, Func.isEmpty(otherExpenseRecord.getExpenseType()), "费用类型不能为空");
|
||||
org.springblade.common.excel.ImportFailureExcelUtil.addValidationError(validationErrors, Func.isNotEmpty(otherExpenseRecord.getExpenseType()) && !EXPENSE_TYPES.contains(otherExpenseRecord.getExpenseType()), "费用类型不正确");
|
||||
org.springblade.common.excel.ImportFailureExcelUtil.addValidationError(validationErrors, Func.isNotEmpty(otherExpenseRecord.getExpenseType()) && !loadExpenseTypeValues().contains(otherExpenseRecord.getExpenseType()), "费用类型不正确");
|
||||
org.springblade.common.excel.ImportFailureExcelUtil.addValidationError(validationErrors, Func.isEmpty(otherExpenseRecord.getVehicleType()), "车船类型不能为空");
|
||||
org.springblade.common.excel.ImportFailureExcelUtil.addValidationError(validationErrors, Func.isNotEmpty(otherExpenseRecord.getVehicleType()) && !VEHICLE.equals(otherExpenseRecord.getVehicleType()) && !SHIP.equals(otherExpenseRecord.getVehicleType()), "车船类型不正确");
|
||||
org.springblade.common.excel.ImportFailureExcelUtil.addValidationError(validationErrors, Func.isEmpty(otherExpenseRecord.getVehicleNo()), "车牌号/船号不能为空");
|
||||
@@ -152,7 +155,7 @@ public class OtherExpenseRecordServiceImpl extends BaseServiceImpl<OtherExpenseR
|
||||
if (Func.isEmpty(otherExpenseRecord.getExpenseType())) {
|
||||
throw new ServiceException("费用类型不能为空");
|
||||
}
|
||||
if (!EXPENSE_TYPES.contains(otherExpenseRecord.getExpenseType())) {
|
||||
if (!loadExpenseTypeValues().contains(otherExpenseRecord.getExpenseType())) {
|
||||
throw new ServiceException("费用类型不正确");
|
||||
}
|
||||
if (Func.isEmpty(otherExpenseRecord.getVehicleType())) {
|
||||
@@ -217,4 +220,17 @@ public class OtherExpenseRecordServiceImpl extends BaseServiceImpl<OtherExpenseR
|
||||
return trimValue.isEmpty() ? null : trimValue;
|
||||
}
|
||||
|
||||
private Set<String> loadExpenseTypeValues() {
|
||||
List<DictBiz> expenseTypes = DictBizCache.getList(EXPENSE_TYPE_DICT_CODE);
|
||||
if (Func.isEmpty(expenseTypes)) {
|
||||
return Set.of();
|
||||
}
|
||||
return expenseTypes.stream()
|
||||
.map(DictBiz::getDictValue)
|
||||
.filter(Objects::nonNull)
|
||||
.map(String::trim)
|
||||
.filter(Func::isNotEmpty)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -1565,11 +1565,11 @@ public class ReceivablePayableDetailServiceImpl
|
||||
|
||||
private BigDecimal calculateRule(Map<String, Object> rule, Waybill waybill) {
|
||||
String element = stringValue(rule, "billingElement", ""); String type = stringValue(rule, "billingType", "");
|
||||
BigDecimal base = measure(rule, waybill); BigDecimal unit = decimal(rule.get("unitPrice"));
|
||||
BigDecimal measuredBase = measure(rule, waybill); BigDecimal unit = decimal(rule.get("unitPrice"));
|
||||
List<Map<String, Object>> ranges = ranges(rule);
|
||||
boolean intervalUnitPrice = "区间单价".equals(type);
|
||||
boolean intervalFlatPrice = type.contains("区间") && type.contains("一口价");
|
||||
if (!intervalUnitPrice && !intervalFlatPrice) base = applyMinimum(base, rule, waybill);
|
||||
BigDecimal base = (!intervalUnitPrice && !intervalFlatPrice) ? applyMinimum(measuredBase, rule, waybill) : measuredBase;
|
||||
if ("固定一口价".equals(type)) return unit.setScale(2, RoundingMode.HALF_UP);
|
||||
if (ranges.isEmpty() || "固定单价".equals(type)) return base.multiply(unit).setScale(2, RoundingMode.HALF_UP);
|
||||
if (intervalFlatPrice) return range(ranges, base).map(r -> decimal(r.get("unitPrice")).signum() == 0 ? unit : decimal(r.get("unitPrice"))).orElse(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
|
||||
|
||||
Reference in New Issue
Block a user