✨ 进行中配载可编辑、汇票可选放开限制,并补充业务部门与待确认回单
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+6
@@ -207,6 +207,12 @@ public class Dept extends TenantEntity {
|
|||||||
@Schema(description = "是否平台公司:0否,1是")
|
@Schema(description = "是否平台公司:0否,1是")
|
||||||
private Integer isPlatformCompany;
|
private Integer isPlatformCompany;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否业务部门:0否,1是
|
||||||
|
*/
|
||||||
|
@Schema(description = "是否业务部门:0否,1是")
|
||||||
|
private Integer isBusinessDept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OA主键,仅同步记录,不对外展示
|
* OA主键,仅同步记录,不对外展示
|
||||||
*/
|
*/
|
||||||
|
|||||||
+4
@@ -199,6 +199,10 @@ public class ContractManage extends TenantEntity {
|
|||||||
@TableField(updateStrategy = FieldStrategy.ALWAYS)
|
@TableField(updateStrategy = FieldStrategy.ALWAYS)
|
||||||
private String changeContent;
|
private String changeContent;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
@Schema(description = "变更类型")
|
||||||
|
private String changeType;
|
||||||
|
|
||||||
@Schema(description = "变更原因")
|
@Schema(description = "变更原因")
|
||||||
@TableField(updateStrategy = FieldStrategy.ALWAYS)
|
@TableField(updateStrategy = FieldStrategy.ALWAYS)
|
||||||
private String changeReason;
|
private String changeReason;
|
||||||
|
|||||||
+11
@@ -260,6 +260,17 @@ public class DeptController extends BladeController {
|
|||||||
return R.data(deptService.listPlatformCompany());
|
return R.data(deptService.listPlatformCompany());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务部门下拉(是否业务部门=是)
|
||||||
|
*/
|
||||||
|
@PreAuth(AuthConstant.PERMIT_ALL)
|
||||||
|
@GetMapping("/business-dept-select")
|
||||||
|
@ApiOperationSupport(order = 12)
|
||||||
|
@Operation(summary = "业务部门下拉", description = "返回是否业务部门=是的部门列表")
|
||||||
|
public R<List<Dept>> businessDeptSelect() {
|
||||||
|
return R.data(deptService.listBusinessDept());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取部门的主管信息
|
* 获取部门的主管信息
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
<result column="mnemonic_code" property="mnemonicCode"/>
|
<result column="mnemonic_code" property="mnemonicCode"/>
|
||||||
<result column="carrier_customer_id" property="carrierCustomerId"/>
|
<result column="carrier_customer_id" property="carrierCustomerId"/>
|
||||||
<result column="is_platform_company" property="isPlatformCompany"/>
|
<result column="is_platform_company" property="isPlatformCompany"/>
|
||||||
|
<result column="is_business_dept" property="isBusinessDept"/>
|
||||||
<result column="sort" property="sort"/>
|
<result column="sort" property="sort"/>
|
||||||
<result column="remark" property="remark"/>
|
<result column="remark" property="remark"/>
|
||||||
<result column="status" property="status"/>
|
<result column="status" property="status"/>
|
||||||
@@ -43,6 +44,7 @@
|
|||||||
<result column="mnemonic_code" property="mnemonicCode"/>
|
<result column="mnemonic_code" property="mnemonicCode"/>
|
||||||
<result column="carrier_customer_id" property="carrierCustomerId"/>
|
<result column="carrier_customer_id" property="carrierCustomerId"/>
|
||||||
<result column="is_platform_company" property="isPlatformCompany"/>
|
<result column="is_platform_company" property="isPlatformCompany"/>
|
||||||
|
<result column="is_business_dept" property="isBusinessDept"/>
|
||||||
<result column="sort" property="sort"/>
|
<result column="sort" property="sort"/>
|
||||||
<result column="remark" property="remark"/>
|
<result column="remark" property="remark"/>
|
||||||
<result column="status" property="status"/>
|
<result column="status" property="status"/>
|
||||||
|
|||||||
+7
@@ -106,6 +106,13 @@ public interface IDeptService extends IService<Dept> {
|
|||||||
*/
|
*/
|
||||||
List<Dept> listPlatformCompany();
|
List<Dept> listPlatformCompany();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务部门下拉(是否业务部门=是)
|
||||||
|
*
|
||||||
|
* @return 业务部门列表
|
||||||
|
*/
|
||||||
|
List<Dept> listBusinessDept();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据部门名称精确匹配获取部门ID集合
|
* 根据部门名称精确匹配获取部门ID集合
|
||||||
*
|
*
|
||||||
|
|||||||
+19
@@ -337,6 +337,18 @@ public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements ID
|
|||||||
return list(queryWrapper);
|
return list(queryWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Dept> listBusinessDept() {
|
||||||
|
LambdaQueryWrapper<Dept> queryWrapper = Wrappers.<Dept>lambdaQuery()
|
||||||
|
.eq(Dept::getIsBusinessDept, 1)
|
||||||
|
.orderByAsc(Dept::getSort)
|
||||||
|
.orderByAsc(Dept::getId);
|
||||||
|
if (!AuthUtil.isAdministrator()) {
|
||||||
|
queryWrapper.eq(Dept::getTenantId, AuthUtil.getTenantId());
|
||||||
|
}
|
||||||
|
return list(queryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDeptIds(String tenantId, String deptNames) {
|
public String getDeptIds(String tenantId, String deptNames) {
|
||||||
List<Dept> deptList = baseMapper.selectList(Wrappers.<Dept>query().lambda().eq(Dept::getTenantId, tenantId).in(Dept::getDeptName, Func.toStrList(deptNames)));
|
List<Dept> deptList = baseMapper.selectList(Wrappers.<Dept>query().lambda().eq(Dept::getTenantId, tenantId).in(Dept::getDeptName, Func.toStrList(deptNames)));
|
||||||
@@ -443,6 +455,7 @@ public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements ID
|
|||||||
rootDept.setIsDeleted(BladeConstant.DB_NOT_DELETED);
|
rootDept.setIsDeleted(BladeConstant.DB_NOT_DELETED);
|
||||||
rootDept.setIsOa(0);
|
rootDept.setIsOa(0);
|
||||||
rootDept.setIsPlatformCompany(0);
|
rootDept.setIsPlatformCompany(0);
|
||||||
|
rootDept.setIsBusinessDept(0);
|
||||||
rootDept.setSyncTime(new Date());
|
rootDept.setSyncTime(new Date());
|
||||||
this.save(rootDept);
|
this.save(rootDept);
|
||||||
log.info("已创建 OA 同步集团顶级 id={} name={} code={}",
|
log.info("已创建 OA 同步集团顶级 id={} name={} code={}",
|
||||||
@@ -536,6 +549,7 @@ public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements ID
|
|||||||
newRoot.setIsDeleted(BladeConstant.DB_NOT_DELETED);
|
newRoot.setIsDeleted(BladeConstant.DB_NOT_DELETED);
|
||||||
newRoot.setIsOa(0);
|
newRoot.setIsOa(0);
|
||||||
newRoot.setIsPlatformCompany(0);
|
newRoot.setIsPlatformCompany(0);
|
||||||
|
newRoot.setIsBusinessDept(0);
|
||||||
newRoot.setSyncTime(new Date());
|
newRoot.setSyncTime(new Date());
|
||||||
this.save(newRoot);
|
this.save(newRoot);
|
||||||
log.info("迁移创建新集团顶级 id={}(来自历史 id={})", newRootId, legacyRootId);
|
log.info("迁移创建新集团顶级 id={}(来自历史 id={})", newRootId, legacyRootId);
|
||||||
@@ -598,6 +612,7 @@ public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements ID
|
|||||||
externalDept.setIsDeleted(BladeConstant.DB_NOT_DELETED);
|
externalDept.setIsDeleted(BladeConstant.DB_NOT_DELETED);
|
||||||
externalDept.setIsOa(0);
|
externalDept.setIsOa(0);
|
||||||
externalDept.setIsPlatformCompany(0);
|
externalDept.setIsPlatformCompany(0);
|
||||||
|
externalDept.setIsBusinessDept(0);
|
||||||
externalDept.setSyncTime(new Date());
|
externalDept.setSyncTime(new Date());
|
||||||
this.save(externalDept);
|
this.save(externalDept);
|
||||||
log.info("已创建外部组织顶级 id={}", externalDept.getId());
|
log.info("已创建外部组织顶级 id={}", externalDept.getId());
|
||||||
@@ -678,6 +693,9 @@ public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements ID
|
|||||||
if (dept.getIsPlatformCompany() == null) {
|
if (dept.getIsPlatformCompany() == null) {
|
||||||
dept.setIsPlatformCompany(0);
|
dept.setIsPlatformCompany(0);
|
||||||
}
|
}
|
||||||
|
if (dept.getIsBusinessDept() == null) {
|
||||||
|
dept.setIsBusinessDept(0);
|
||||||
|
}
|
||||||
// 排序未填时默认 1
|
// 排序未填时默认 1
|
||||||
if (dept.getSort() == null) {
|
if (dept.getSort() == null) {
|
||||||
dept.setSort(1);
|
dept.setSort(1);
|
||||||
@@ -804,6 +822,7 @@ public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements ID
|
|||||||
dept.setIsDeleted(BladeConstant.DB_NOT_DELETED);
|
dept.setIsDeleted(BladeConstant.DB_NOT_DELETED);
|
||||||
dept.setIsOa(1);
|
dept.setIsOa(1);
|
||||||
dept.setIsPlatformCompany(0);
|
dept.setIsPlatformCompany(0);
|
||||||
|
dept.setIsBusinessDept(0);
|
||||||
dept.setSyncTime(new Date());
|
dept.setSyncTime(new Date());
|
||||||
boolean saved = save(dept);
|
boolean saved = save(dept);
|
||||||
if (saved) {
|
if (saved) {
|
||||||
|
|||||||
+24
-1
@@ -924,7 +924,8 @@ public class OASyncServiceImpl implements IOASyncService {
|
|||||||
.select(Dept::getId, Dept::getDeptCode, Dept::getDeptName, Dept::getFullName,
|
.select(Dept::getId, Dept::getDeptCode, Dept::getDeptName, Dept::getFullName,
|
||||||
Dept::getOaModified, Dept::getParentId, Dept::getOaId, Dept::getBelongCompanyCode,
|
Dept::getOaModified, Dept::getParentId, Dept::getOaId, Dept::getBelongCompanyCode,
|
||||||
Dept::getParentCode, Dept::getOaSupSubComId,
|
Dept::getParentCode, Dept::getOaSupSubComId,
|
||||||
Dept::getContractCodePrefix, Dept::getContractInitialSerial));
|
Dept::getContractCodePrefix, Dept::getContractInitialSerial,
|
||||||
|
Dept::getIsPlatformCompany, Dept::getIsBusinessDept));
|
||||||
Map<String, Dept> byOaId = new HashMap<>();
|
Map<String, Dept> byOaId = new HashMap<>();
|
||||||
for (Dept dept : deptList) {
|
for (Dept dept : deptList) {
|
||||||
if (StringUtils.isNotBlank(dept.getOaId())) {
|
if (StringUtils.isNotBlank(dept.getOaId())) {
|
||||||
@@ -989,6 +990,8 @@ public class OASyncServiceImpl implements IOASyncService {
|
|||||||
}
|
}
|
||||||
// OA 不同步合同本地配置:保留已有值,并把 -1 空占位规范为 null,避免 ALWAYS 策略写回 -1/清空
|
// OA 不同步合同本地配置:保留已有值,并把 -1 空占位规范为 null,避免 ALWAYS 策略写回 -1/清空
|
||||||
preserveLocalContractFields(dept, existing);
|
preserveLocalContractFields(dept, existing);
|
||||||
|
// OA 不同步「是否平台公司 / 是否业务部门」:更新时强制保留本地已配置值,新增默认否
|
||||||
|
preserveLocalBizFlags(dept, existing);
|
||||||
normalizeContractInitialSerial(dept);
|
normalizeContractInitialSerial(dept);
|
||||||
if (StringUtils.isNotBlank(dept.getDeptCode())) {
|
if (StringUtils.isNotBlank(dept.getDeptCode())) {
|
||||||
deptIdByCode.put(dept.getDeptCode(), dept.getId());
|
deptIdByCode.put(dept.getDeptCode(), dept.getId());
|
||||||
@@ -1066,6 +1069,26 @@ public class OASyncServiceImpl implements IOASyncService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OA 同步不携带本地业务标志:更新时保留已配置的「是否平台公司 / 是否业务部门」,新增默认否。
|
||||||
|
*/
|
||||||
|
private void preserveLocalBizFlags(Dept incoming, Dept existing) {
|
||||||
|
if (incoming == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (existing != null) {
|
||||||
|
incoming.setIsPlatformCompany(existing.getIsPlatformCompany() != null ? existing.getIsPlatformCompany() : 0);
|
||||||
|
incoming.setIsBusinessDept(existing.getIsBusinessDept() != null ? existing.getIsBusinessDept() : 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (incoming.getIsPlatformCompany() == null) {
|
||||||
|
incoming.setIsPlatformCompany(0);
|
||||||
|
}
|
||||||
|
if (incoming.getIsBusinessDept() == null) {
|
||||||
|
incoming.setIsBusinessDept(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 合同初始流水号 -1 为空占位,同步落库前规范为 null。
|
* 合同初始流水号 -1 为空占位,同步落库前规范为 null。
|
||||||
*/
|
*/
|
||||||
|
|||||||
+1
-32
@@ -107,7 +107,7 @@ public class BillLedgerServiceImpl extends BaseServiceImpl<BillLedgerMapper, Bil
|
|||||||
private List<BillLedgerVO> availableList(String keyword, Long deptId, Long selectedId, String payerName,
|
private List<BillLedgerVO> availableList(String keyword, Long deptId, Long selectedId, String payerName,
|
||||||
String payeeName) {
|
String payeeName) {
|
||||||
LocalDate today = LocalDate.now();
|
LocalDate today = LocalDate.now();
|
||||||
// 未到期且有余额;收票且部门可用,或出票/收票单位与结算收付款方一致(开票、收票都可)
|
// 可选汇票:未到期且可用余额 > 0(已选中的可回显);不再按部门、开票/收票类型、结算收付款方过滤
|
||||||
return list(Wrappers.<BillLedger>lambdaQuery()
|
return list(Wrappers.<BillLedger>lambdaQuery()
|
||||||
.and(Func.isNotEmpty(keyword), wrapper -> wrapper.like(BillLedger::getBillNo, keyword)
|
.and(Func.isNotEmpty(keyword), wrapper -> wrapper.like(BillLedger::getBillNo, keyword)
|
||||||
.or().like(BillLedger::getIssuerName, keyword)
|
.or().like(BillLedger::getIssuerName, keyword)
|
||||||
@@ -119,35 +119,10 @@ public class BillLedgerServiceImpl extends BaseServiceImpl<BillLedgerMapper, Bil
|
|||||||
.or(selectedId != null, child -> child.eq(BillLedger::getId, selectedId)))
|
.or(selectedId != null, child -> child.eq(BillLedger::getId, selectedId)))
|
||||||
.orderByAsc(BillLedger::getMaturityDate)
|
.orderByAsc(BillLedger::getMaturityDate)
|
||||||
.orderByDesc(BillLedger::getCreateTime)).stream()
|
.orderByDesc(BillLedger::getCreateTime)).stream()
|
||||||
.filter(item -> selectedId != null && Objects.equals(item.getId(), selectedId)
|
|
||||||
|| selectableBill(item, deptId, payerName, payeeName))
|
|
||||||
.map(item -> BillLedgerWrapper.build().entityVO(item))
|
.map(item -> BillLedgerWrapper.build().entityVO(item))
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 收票且当前部门在可用范围内,或出票单位、收票单位与结算付款方、收款方一致(顺序不限)。
|
|
||||||
*/
|
|
||||||
private boolean selectableBill(BillLedger ledger, Long deptId, String payerName, String payeeName) {
|
|
||||||
boolean receivedAndDept = "received".equals(ledger.getBillType()) && departmentAvailable(ledger, deptId);
|
|
||||||
return receivedAndDept || partiesMatch(ledger.getIssuerName(), ledger.getReceiverName(), payerName, payeeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean partiesMatch(String issuerName, String receiverName, String payerName, String payeeName) {
|
|
||||||
String issuer = trimName(issuerName);
|
|
||||||
String receiver = trimName(receiverName);
|
|
||||||
String payer = trimName(payerName);
|
|
||||||
String payee = trimName(payeeName);
|
|
||||||
if (issuer.isEmpty() || receiver.isEmpty() || payer.isEmpty() || payee.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return (issuer.equals(payer) && receiver.equals(payee)) || (issuer.equals(payee) && receiver.equals(payer));
|
|
||||||
}
|
|
||||||
|
|
||||||
private String trimName(String value) {
|
|
||||||
return value == null ? "" : value.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public Long submit(BillLedgerSaveRequest request) {
|
public Long submit(BillLedgerSaveRequest request) {
|
||||||
@@ -292,12 +267,6 @@ public class BillLedgerServiceImpl extends BaseServiceImpl<BillLedgerMapper, Bil
|
|||||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean departmentAvailable(BillLedger ledger, Long deptId) {
|
|
||||||
List<?> values = parseArray(ledger.getAvailableDeptIdsJson(), "可用部门");
|
|
||||||
if (values.stream().anyMatch(value -> "all".equals(String.valueOf(value)))) return true;
|
|
||||||
return deptId == null || values.stream().anyMatch(value -> String.valueOf(deptId).equals(String.valueOf(value)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<?> parseArray(String value, String name) {
|
private List<?> parseArray(String value, String name) {
|
||||||
if (Func.isEmpty(value)) return List.of();
|
if (Func.isEmpty(value)) return List.of();
|
||||||
try {
|
try {
|
||||||
|
|||||||
+4
-20
@@ -32,7 +32,6 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import org.springblade.core.log.exception.ServiceException;
|
import org.springblade.core.log.exception.ServiceException;
|
||||||
import org.springblade.core.mp.base.BaseServiceImpl;
|
import org.springblade.core.mp.base.BaseServiceImpl;
|
||||||
import org.springblade.core.secure.utils.AuthUtil;
|
import org.springblade.core.secure.utils.AuthUtil;
|
||||||
import org.springblade.core.tool.jackson.JsonUtil;
|
|
||||||
import org.springblade.core.tool.utils.Func;
|
import org.springblade.core.tool.utils.Func;
|
||||||
import org.springblade.system.cache.SysCache;
|
import org.springblade.system.cache.SysCache;
|
||||||
import org.springblade.transport.constant.TransportBusiConstant;
|
import org.springblade.transport.constant.TransportBusiConstant;
|
||||||
@@ -112,7 +111,7 @@ public class BillPaymentServiceImpl extends BaseServiceImpl<BillPaymentMapper, B
|
|||||||
String deptName = required(SysCache.getDeptName(deptId), "使用部门", 100);
|
String deptName = required(SysCache.getDeptName(deptId), "使用部门", 100);
|
||||||
BillLedger ledger = lockedBill(request.getBillLedgerId());
|
BillLedger ledger = lockedBill(request.getBillLedgerId());
|
||||||
BigDecimal usedAmount = positive(request.getUsedAmount(), "本次使用");
|
BigDecimal usedAmount = positive(request.getUsedAmount(), "本次使用");
|
||||||
validateLedgerAmount(ledger, usedAmount, deptId);
|
validateLedgerAmount(ledger, usedAmount);
|
||||||
if (entity.getId() == null) {
|
if (entity.getId() == null) {
|
||||||
entity.setPaymentNo(nextNo());
|
entity.setPaymentNo(nextNo());
|
||||||
entity.setApprovalStatus(TransportBusiConstant.DRAFT);
|
entity.setApprovalStatus(TransportBusiConstant.DRAFT);
|
||||||
@@ -165,7 +164,7 @@ public class BillPaymentServiceImpl extends BaseServiceImpl<BillPaymentMapper, B
|
|||||||
throw new ServiceException("仅审批中的汇票付款允许审核");
|
throw new ServiceException("仅审批中的汇票付款允许审核");
|
||||||
}
|
}
|
||||||
BillLedger ledger = lockedBill(entity.getBillLedgerId());
|
BillLedger ledger = lockedBill(entity.getBillLedgerId());
|
||||||
validateLedgerAmount(ledger, entity.getUsedAmount(), entity.getDeptId());
|
validateLedgerAmount(ledger, entity.getUsedAmount());
|
||||||
BillLedgerUsage exists = usageMapper.selectOne(Wrappers.<BillLedgerUsage>lambdaQuery()
|
BillLedgerUsage exists = usageMapper.selectOne(Wrappers.<BillLedgerUsage>lambdaQuery()
|
||||||
.eq(BillLedgerUsage::getBillPaymentId, entity.getId())
|
.eq(BillLedgerUsage::getBillPaymentId, entity.getId())
|
||||||
.eq(BillLedgerUsage::getUsageStatus, TransportBusiConstant.APPROVED)
|
.eq(BillLedgerUsage::getUsageStatus, TransportBusiConstant.APPROVED)
|
||||||
@@ -245,13 +244,13 @@ public class BillPaymentServiceImpl extends BaseServiceImpl<BillPaymentMapper, B
|
|||||||
|
|
||||||
private void validateStoredAmount(BillPayment entity) {
|
private void validateStoredAmount(BillPayment entity) {
|
||||||
BillLedger ledger = lockedBill(entity.getBillLedgerId());
|
BillLedger ledger = lockedBill(entity.getBillLedgerId());
|
||||||
validateLedgerAmount(ledger, entity.getUsedAmount(), entity.getDeptId());
|
validateLedgerAmount(ledger, entity.getUsedAmount());
|
||||||
entity.setBillNo(ledger.getBillNo());
|
entity.setBillNo(ledger.getBillNo());
|
||||||
entity.setFaceAmount(ledger.getFaceAmount());
|
entity.setFaceAmount(ledger.getFaceAmount());
|
||||||
entity.setAvailableBalance(ledger.getAvailableBalance());
|
entity.setAvailableBalance(ledger.getAvailableBalance());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateLedgerAmount(BillLedger ledger, BigDecimal usedAmount, Long deptId) {
|
private void validateLedgerAmount(BillLedger ledger, BigDecimal usedAmount) {
|
||||||
if (usedAmount == null || usedAmount.compareTo(BigDecimal.ZERO) <= 0) {
|
if (usedAmount == null || usedAmount.compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
throw new ServiceException("本次使用必须大于0");
|
throw new ServiceException("本次使用必须大于0");
|
||||||
}
|
}
|
||||||
@@ -261,21 +260,6 @@ public class BillPaymentServiceImpl extends BaseServiceImpl<BillPaymentMapper, B
|
|||||||
if (usedAmount.compareTo(money(ledger.getAvailableBalance())) > 0) {
|
if (usedAmount.compareTo(money(ledger.getAvailableBalance())) > 0) {
|
||||||
throw new ServiceException("本次使用不能超过汇票可用余额");
|
throw new ServiceException("本次使用不能超过汇票可用余额");
|
||||||
}
|
}
|
||||||
if (!departmentAvailable(ledger, deptId)) {
|
|
||||||
throw new ServiceException("当前使用部门不在汇票可用部门范围内");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean departmentAvailable(BillLedger ledger, Long deptId) {
|
|
||||||
if (Func.isEmpty(ledger.getAvailableDeptIdsJson())) return false;
|
|
||||||
try {
|
|
||||||
Object parsed = JsonUtil.parse(ledger.getAvailableDeptIdsJson(), List.class);
|
|
||||||
if (!(parsed instanceof List<?> values)) return false;
|
|
||||||
if (values.stream().anyMatch(item -> "all".equals(String.valueOf(item)))) return true;
|
|
||||||
return deptId != null && values.stream().anyMatch(item -> String.valueOf(deptId).equals(String.valueOf(item)));
|
|
||||||
} catch (Exception exception) {
|
|
||||||
throw new ServiceException("汇票可用部门配置不正确");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BillLedger lockedBill(Long id) {
|
private BillLedger lockedBill(Long id) {
|
||||||
|
|||||||
+78
-22
@@ -83,6 +83,8 @@ public class ContractManageServiceImpl extends BaseServiceImpl<ContractManageMap
|
|||||||
private static final String ARCHIVE_STATUS_PENDING = "未归档";
|
private static final String ARCHIVE_STATUS_PENDING = "未归档";
|
||||||
private static final String ARCHIVE_STATUS_ARCHIVED = "已归档";
|
private static final String ARCHIVE_STATUS_ARCHIVED = "已归档";
|
||||||
private static final String FILE_TYPE_SEAL_ARCHIVE = "双章归档文件";
|
private static final String FILE_TYPE_SEAL_ARCHIVE = "双章归档文件";
|
||||||
|
private static final String CHANGE_TYPE_INFO = "合同信息变更";
|
||||||
|
private static final String CHANGE_TYPE_SETTLEMENT = "结算规则变更";
|
||||||
private static final long TEMPORARY_VALIDITY_DAYS = 30L;
|
private static final long TEMPORARY_VALIDITY_DAYS = 30L;
|
||||||
private static final BigDecimal TAX_RATE_MIN = BigDecimal.ZERO;
|
private static final BigDecimal TAX_RATE_MIN = BigDecimal.ZERO;
|
||||||
private static final BigDecimal TAX_RATE_MAX = BigDecimal.valueOf(100);
|
private static final BigDecimal TAX_RATE_MAX = BigDecimal.valueOf(100);
|
||||||
@@ -285,45 +287,99 @@ public class ContractManageServiceImpl extends BaseServiceImpl<ContractManageMap
|
|||||||
|| !List.of(STATUS_APPROVED, STATUS_CHANGE_APPROVED, STATUS_CHANGE_REJECTED).contains(source.getApprovalStatus())) {
|
|| !List.of(STATUS_APPROVED, STATUS_CHANGE_APPROVED, STATUS_CHANGE_REJECTED).contains(source.getApprovalStatus())) {
|
||||||
throw new ServiceException("当前合同状态不允许发起变更");
|
throw new ServiceException("当前合同状态不允许发起变更");
|
||||||
}
|
}
|
||||||
TransportBusinessSupport.validateRequired(request.getSettlementCurrency(), "请选择结算币种");
|
String changeType = resolveChangeType(request.getChangeType());
|
||||||
|
boolean settlementRuleOnly = Objects.equals(changeType, CHANGE_TYPE_SETTLEMENT);
|
||||||
String changeReason = TransportBusinessSupport.trimToNull(request.getChangeReason());
|
String changeReason = TransportBusinessSupport.trimToNull(request.getChangeReason());
|
||||||
if (Func.isEmpty(changeReason) && Objects.equals(source.getApprovalStatus(), STATUS_CHANGE_REJECTED)) {
|
if (Func.isEmpty(changeReason) && Objects.equals(source.getApprovalStatus(), STATUS_CHANGE_REJECTED)) {
|
||||||
changeReason = resolveResubmitChangeReason(source);
|
changeReason = resolveResubmitChangeReason(source);
|
||||||
}
|
}
|
||||||
TransportBusinessSupport.validateLength(changeReason, 500, "变更原因不能超过500字");
|
TransportBusinessSupport.validateLength(changeReason, 500, "变更原因不能超过500字");
|
||||||
ContractManage candidate = new ContractManage();
|
|
||||||
BeanUtil.copyProperties(source, candidate);
|
|
||||||
candidate.setPartyB(TransportBusinessSupport.trimToNull(request.getPartyB()));
|
|
||||||
validateContractPartyCombinationUnique(candidate);
|
|
||||||
validateBillingPlans(request.getBillingPlanJson());
|
validateBillingPlans(request.getBillingPlanJson());
|
||||||
validatePaymentRatios(request.getPaymentRatioJson());
|
|
||||||
Map<String, Object> beforeData = buildContractChangeSnapshot(source);
|
Map<String, Object> beforeData = buildContractChangeSnapshot(source);
|
||||||
applyContractNo(source, request.getContractNo(), false);
|
if (settlementRuleOnly) {
|
||||||
source.setContractName(request.getContractName()); source.setPartyB(request.getPartyB());
|
applySettlementRuleChange(source, request);
|
||||||
source.setStartDate(request.getStartDate()); source.setEndDate(request.getEndDate()); source.setContractFormat(request.getContractFormat());
|
} else {
|
||||||
source.setSettlementMode(request.getSettlementMode()); source.setLegalSealFlag(request.getLegalSealFlag()); source.setCopyCount(request.getCopyCount());
|
applyContractInfoChange(source, request);
|
||||||
source.setSettlementCurrency(TransportBusinessSupport.trimToNull(request.getSettlementCurrency())); source.setInvoiceCycle(request.getInvoiceCycle());
|
}
|
||||||
source.setPaymentDays(request.getPaymentDays()); source.setRemark(request.getRemark()); source.setBillingEnabled(request.getBillingEnabled()); source.setFeeGenerationMode(request.getFeeGenerationMode());
|
|
||||||
source.setContractAmount(request.getContractAmount()); source.setTemplateFlag(request.getTemplateFlag());
|
|
||||||
source.setOriginalContractNo(TransportBusinessSupport.trimToNull(request.getOriginalContractNo()));
|
|
||||||
source.setElectronicSealFlag(request.getElectronicSealFlag());
|
|
||||||
normalizeOptionalIntegerFields(source);
|
|
||||||
validateContractAmountRequired(source);
|
|
||||||
validateAdditionalFields(source);
|
|
||||||
source.setBillingPlanJson(request.getBillingPlanJson()); source.setSettlementRuleJson(request.getSettlementRuleJson()); source.setPreSettlementConfigJson(request.getPreSettlementConfigJson()); source.setFormalSettlementConfigJson(request.getFormalSettlementConfigJson()); source.setPaymentRatioJson(request.getPaymentRatioJson());
|
|
||||||
source.setContractFileJson(request.getContractFileJson()); source.setAttachmentsJson(request.getAttachmentsJson());
|
|
||||||
source.setChangeAttachmentsJson(TransportBusinessSupport.trimToNull(request.getChangeAttachmentsJson()));
|
|
||||||
Map<String, Object> afterData = buildContractChangeSnapshot(source);
|
Map<String, Object> afterData = buildContractChangeSnapshot(source);
|
||||||
retainChangedSnapshotFields(beforeData, afterData);
|
retainChangedSnapshotFields(beforeData, afterData);
|
||||||
source.setApprovalStatus(STATUS_CHANGE_REVIEWING);
|
source.setApprovalStatus(STATUS_CHANGE_REVIEWING);
|
||||||
source.setChangeContent(TransportBusinessSupport.trimToNull(request.getChangeContent()));
|
source.setChangeContent(TransportBusinessSupport.trimToNull(request.getChangeContent()));
|
||||||
source.setChangeReason(changeReason);
|
source.setChangeReason(changeReason);
|
||||||
|
source.setChangeAttachmentsJson(TransportBusinessSupport.trimToNull(request.getChangeAttachmentsJson()));
|
||||||
source.setCurrentNode("合同变更审批");
|
source.setCurrentNode("合同变更审批");
|
||||||
source.setCurrentProcessor("待处理");
|
source.setCurrentProcessor("待处理");
|
||||||
appendChangeRecord(source, "合同信息变更", changeReason, STATUS_CHANGE_REVIEWING, "审核中", beforeData, afterData);
|
appendChangeRecord(source, changeType, changeReason, STATUS_CHANGE_REVIEWING, "审核中", beforeData, afterData);
|
||||||
return updateById(source);
|
return updateById(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析并校验合同变更类型,兼容历史未传类型的请求。
|
||||||
|
*/
|
||||||
|
private String resolveChangeType(String changeType) {
|
||||||
|
String normalized = TransportBusinessSupport.trimToNull(changeType);
|
||||||
|
if (Func.isEmpty(normalized)) {
|
||||||
|
return CHANGE_TYPE_INFO;
|
||||||
|
}
|
||||||
|
if (!List.of(CHANGE_TYPE_INFO, CHANGE_TYPE_SETTLEMENT).contains(normalized)) {
|
||||||
|
throw new ServiceException("请选择变更类型");
|
||||||
|
}
|
||||||
|
return normalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结算规则变更:仅允许更新计费信息与结算单规则。
|
||||||
|
*/
|
||||||
|
private void applySettlementRuleChange(ContractManage source, ContractManage request) {
|
||||||
|
source.setBillingEnabled(request.getBillingEnabled());
|
||||||
|
source.setFeeGenerationMode(request.getFeeGenerationMode());
|
||||||
|
source.setBillingPlanJson(request.getBillingPlanJson());
|
||||||
|
source.setSettlementRuleJson(request.getSettlementRuleJson());
|
||||||
|
source.setPreSettlementConfigJson(request.getPreSettlementConfigJson());
|
||||||
|
source.setFormalSettlementConfigJson(request.getFormalSettlementConfigJson());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合同信息变更:更新合同基本信息、计费/结算规则、付款比例及附件。
|
||||||
|
*/
|
||||||
|
private void applyContractInfoChange(ContractManage source, ContractManage request) {
|
||||||
|
TransportBusinessSupport.validateRequired(request.getSettlementCurrency(), "请选择结算币种");
|
||||||
|
ContractManage candidate = new ContractManage();
|
||||||
|
BeanUtil.copyProperties(source, candidate);
|
||||||
|
candidate.setPartyB(TransportBusinessSupport.trimToNull(request.getPartyB()));
|
||||||
|
validateContractPartyCombinationUnique(candidate);
|
||||||
|
validatePaymentRatios(request.getPaymentRatioJson());
|
||||||
|
applyContractNo(source, request.getContractNo(), false);
|
||||||
|
source.setContractName(request.getContractName());
|
||||||
|
source.setPartyB(request.getPartyB());
|
||||||
|
source.setStartDate(request.getStartDate());
|
||||||
|
source.setEndDate(request.getEndDate());
|
||||||
|
source.setContractFormat(request.getContractFormat());
|
||||||
|
source.setSettlementMode(request.getSettlementMode());
|
||||||
|
source.setLegalSealFlag(request.getLegalSealFlag());
|
||||||
|
source.setCopyCount(request.getCopyCount());
|
||||||
|
source.setSettlementCurrency(TransportBusinessSupport.trimToNull(request.getSettlementCurrency()));
|
||||||
|
source.setInvoiceCycle(request.getInvoiceCycle());
|
||||||
|
source.setPaymentDays(request.getPaymentDays());
|
||||||
|
source.setRemark(request.getRemark());
|
||||||
|
source.setBillingEnabled(request.getBillingEnabled());
|
||||||
|
source.setFeeGenerationMode(request.getFeeGenerationMode());
|
||||||
|
source.setContractAmount(request.getContractAmount());
|
||||||
|
source.setTemplateFlag(request.getTemplateFlag());
|
||||||
|
source.setOriginalContractNo(TransportBusinessSupport.trimToNull(request.getOriginalContractNo()));
|
||||||
|
source.setElectronicSealFlag(request.getElectronicSealFlag());
|
||||||
|
normalizeOptionalIntegerFields(source);
|
||||||
|
validateContractAmountRequired(source);
|
||||||
|
validateAdditionalFields(source);
|
||||||
|
source.setBillingPlanJson(request.getBillingPlanJson());
|
||||||
|
source.setSettlementRuleJson(request.getSettlementRuleJson());
|
||||||
|
source.setPreSettlementConfigJson(request.getPreSettlementConfigJson());
|
||||||
|
source.setFormalSettlementConfigJson(request.getFormalSettlementConfigJson());
|
||||||
|
source.setPaymentRatioJson(request.getPaymentRatioJson());
|
||||||
|
source.setContractFileJson(request.getContractFileJson());
|
||||||
|
source.setAttachmentsJson(request.getAttachmentsJson());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public boolean updateAttachments(ContractManage contractManage) {
|
public boolean updateAttachments(ContractManage contractManage) {
|
||||||
|
|||||||
+23
-7
@@ -107,6 +107,7 @@ public class DriverWaybillServiceImpl implements IDriverWaybillService {
|
|||||||
private static final String STATUS_WAITING_DISPATCH = "waiting_dispatch";
|
private static final String STATUS_WAITING_DISPATCH = "waiting_dispatch";
|
||||||
private static final String STATUS_DISPATCHING = "dispatching";
|
private static final String STATUS_DISPATCHING = "dispatching";
|
||||||
private static final String STATUS_RUNNING = "running";
|
private static final String STATUS_RUNNING = "running";
|
||||||
|
private static final String STATUS_PENDING_RETURN = WaybillProcessSupport.STATUS_PENDING_RETURN;
|
||||||
private static final String STATUS_COMPLETED = "completed";
|
private static final String STATUS_COMPLETED = "completed";
|
||||||
private static final String STATUS_CANCELLED = "cancelled";
|
private static final String STATUS_CANCELLED = "cancelled";
|
||||||
|
|
||||||
@@ -118,9 +119,10 @@ public class DriverWaybillServiceImpl implements IDriverWaybillService {
|
|||||||
private static final List<String> PENDING_STATUSES = Arrays.asList(
|
private static final List<String> PENDING_STATUSES = Arrays.asList(
|
||||||
STATUS_PENDING, STATUS_WAITING_DISPATCH, STATUS_DISPATCHING
|
STATUS_PENDING, STATUS_WAITING_DISPATCH, STATUS_DISPATCHING
|
||||||
);
|
);
|
||||||
/** Tab「全部」统计口径:待接 + 运输中 + 已完成(不含已取消) */
|
/** Tab「全部」统计口径:待接 + 运输中 + 待确认回单 + 已完成(不含已取消) */
|
||||||
private static final List<String> TAB_ALL_STATUSES = Arrays.asList(
|
private static final List<String> TAB_ALL_STATUSES = Arrays.asList(
|
||||||
STATUS_PENDING, STATUS_WAITING_DISPATCH, STATUS_DISPATCHING, STATUS_RUNNING, STATUS_COMPLETED
|
STATUS_PENDING, STATUS_WAITING_DISPATCH, STATUS_DISPATCHING, STATUS_RUNNING,
|
||||||
|
STATUS_PENDING_RETURN, STATUS_COMPLETED
|
||||||
);
|
);
|
||||||
/** 允许完成运单的业务状态 */
|
/** 允许完成运单的业务状态 */
|
||||||
private static final List<String> COMPLETABLE_STATUSES = Arrays.asList(
|
private static final List<String> COMPLETABLE_STATUSES = Arrays.asList(
|
||||||
@@ -520,22 +522,35 @@ public class DriverWaybillServiceImpl implements IDriverWaybillService {
|
|||||||
nodePunchMapper.insert(punch);
|
nodePunchMapper.insert(punch);
|
||||||
|
|
||||||
advanceCurrentProcessNode(waybill, nodeCfg);
|
advanceCurrentProcessNode(waybill, nodeCfg);
|
||||||
// 末位打卡节点是到货/卸货/签收、且回单无需确认完成时,本次打卡一并把运单置为完成;
|
// 末位打卡节点是到货/卸货/签收时:
|
||||||
|
// - 回单无需确认 → 直接完成;
|
||||||
|
// - 回单需确认 → 进入「待确认回单」,等运管员批量/单条完成后才变已完成。
|
||||||
// isLastDriverPunchNode 与 returnNeedsNoConfirmation 传的就是上面那份 processJson,未再调 resolveProcessJson 取过程配置。
|
// isLastDriverPunchNode 与 returnNeedsNoConfirmation 传的就是上面那份 processJson,未再调 resolveProcessJson 取过程配置。
|
||||||
String nodeKey = WaybillProcessSupport.nodeKey(nodeCfg);
|
String nodeKey = WaybillProcessSupport.nodeKey(nodeCfg);
|
||||||
String nodeName = WaybillProcessSupport.nodeName(nodeCfg);
|
String nodeName = WaybillProcessSupport.nodeName(nodeCfg);
|
||||||
boolean completed = false;
|
boolean completed = false;
|
||||||
if (WaybillProcessSupport.isLastDriverPunchNode(processJson, nodeKey)
|
if (WaybillProcessSupport.isLastDriverPunchNode(processJson, nodeKey)
|
||||||
&& WaybillProcessSupport.isDeliveryNode(nodeKey, nodeName)
|
&& WaybillProcessSupport.isDeliveryNode(nodeKey, nodeName)
|
||||||
&& WaybillProcessSupport.returnNeedsNoConfirmation(processJson)
|
|
||||||
&& canAutoCompleteWaybill(waybill)) {
|
&& canAutoCompleteWaybill(waybill)) {
|
||||||
completed = waybillService.completeWithoutDeptCheck(waybill.getId());
|
if (WaybillProcessSupport.returnNeedsNoConfirmation(processJson)) {
|
||||||
|
completed = waybillService.completeWithoutDeptCheck(waybill.getId());
|
||||||
|
} else {
|
||||||
|
markPendingReturn(waybill);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DriverNodePunchVO vo = toNodePunchVO(punch);
|
DriverNodePunchVO vo = toNodePunchVO(punch);
|
||||||
vo.setWaybillCompleted(completed);
|
vo.setWaybillCompleted(completed);
|
||||||
return vo;
|
return vo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 司机末位打卡完成且回单需内部确认时,将运单置为待确认回单。
|
||||||
|
*/
|
||||||
|
private void markPendingReturn(Waybill waybill) {
|
||||||
|
waybill.setBusinessStatus(STATUS_PENDING_RETURN);
|
||||||
|
waybillService.updateById(waybill);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public boolean accept(Long id) {
|
public boolean accept(Long id) {
|
||||||
@@ -844,7 +859,7 @@ public class DriverWaybillServiceImpl implements IDriverWaybillService {
|
|||||||
switch (status) {
|
switch (status) {
|
||||||
case 0 -> wrapper.in(Waybill::getBusinessStatus, PENDING_STATUSES);
|
case 0 -> wrapper.in(Waybill::getBusinessStatus, PENDING_STATUSES);
|
||||||
case 1 -> wrapper.in(Waybill::getBusinessStatus, COMPLETABLE_STATUSES);
|
case 1 -> wrapper.in(Waybill::getBusinessStatus, COMPLETABLE_STATUSES);
|
||||||
case 2 -> wrapper.eq(Waybill::getBusinessStatus, STATUS_COMPLETED);
|
case 2 -> wrapper.in(Waybill::getBusinessStatus, STATUS_COMPLETED, STATUS_PENDING_RETURN);
|
||||||
case 3 -> wrapper.eq(Waybill::getBusinessStatus, STATUS_CANCELLED);
|
case 3 -> wrapper.eq(Waybill::getBusinessStatus, STATUS_CANCELLED);
|
||||||
default -> wrapper.in(Waybill::getBusinessStatus, TAB_ALL_STATUSES);
|
default -> wrapper.in(Waybill::getBusinessStatus, TAB_ALL_STATUSES);
|
||||||
}
|
}
|
||||||
@@ -2004,7 +2019,8 @@ public class DriverWaybillServiceImpl implements IDriverWaybillService {
|
|||||||
return switch (businessStatus) {
|
return switch (businessStatus) {
|
||||||
case STATUS_PENDING, STATUS_WAITING_DISPATCH, STATUS_DISPATCHING -> 0;
|
case STATUS_PENDING, STATUS_WAITING_DISPATCH, STATUS_DISPATCHING -> 0;
|
||||||
case STATUS_RUNNING -> 1;
|
case STATUS_RUNNING -> 1;
|
||||||
case STATUS_COMPLETED -> 2;
|
// 待确认回单:司机侧节点已打完,对司机按已完成展示
|
||||||
|
case STATUS_PENDING_RETURN, STATUS_COMPLETED -> 2;
|
||||||
case STATUS_CANCELLED -> 3;
|
case STATUS_CANCELLED -> 3;
|
||||||
default -> null;
|
default -> null;
|
||||||
};
|
};
|
||||||
|
|||||||
+181
-4
@@ -20,9 +20,11 @@ import org.springblade.system.pojo.entity.Dept;
|
|||||||
import org.springblade.transport.excel.LoadingManageExcel;
|
import org.springblade.transport.excel.LoadingManageExcel;
|
||||||
import org.springblade.transport.mapper.LoadingManageMapper;
|
import org.springblade.transport.mapper.LoadingManageMapper;
|
||||||
import org.springblade.transport.mapper.WaybillMapper;
|
import org.springblade.transport.mapper.WaybillMapper;
|
||||||
|
import org.springblade.transport.mapper.WaybillNodePunchMapper;
|
||||||
import org.springblade.transport.pojo.entity.ContractManage;
|
import org.springblade.transport.pojo.entity.ContractManage;
|
||||||
import org.springblade.transport.pojo.entity.LoadingManage;
|
import org.springblade.transport.pojo.entity.LoadingManage;
|
||||||
import org.springblade.transport.pojo.entity.Waybill;
|
import org.springblade.transport.pojo.entity.Waybill;
|
||||||
|
import org.springblade.transport.pojo.entity.WaybillNodePunch;
|
||||||
import org.springblade.transport.pojo.vo.BusinessRemoveResultVO;
|
import org.springblade.transport.pojo.vo.BusinessRemoveResultVO;
|
||||||
import org.springblade.transport.pojo.vo.LoadingCarrierContractVO;
|
import org.springblade.transport.pojo.vo.LoadingCarrierContractVO;
|
||||||
import org.springblade.transport.pojo.vo.LoadingManageVO;
|
import org.springblade.transport.pojo.vo.LoadingManageVO;
|
||||||
@@ -74,6 +76,9 @@ public class LoadingManageServiceImpl extends BaseServiceImpl<LoadingManageMappe
|
|||||||
@Resource
|
@Resource
|
||||||
private WaybillMapper waybillMapper;
|
private WaybillMapper waybillMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private WaybillNodePunchMapper waybillNodePunchMapper;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private IContractManageService contractManageService;
|
private IContractManageService contractManageService;
|
||||||
|
|
||||||
@@ -139,10 +144,26 @@ public class LoadingManageServiceImpl extends BaseServiceImpl<LoadingManageMappe
|
|||||||
loadingManage.setLoadingNo(nextCode());
|
loadingManage.setLoadingNo(nextCode());
|
||||||
}
|
}
|
||||||
validateCarrierContract(loadingManage, false);
|
validateCarrierContract(loadingManage, false);
|
||||||
|
if (STATUS_RUNNING.equals(businessStatus) && Func.isNotEmpty(loadingManage.getId())) {
|
||||||
|
LoadingManage oldRecord = getById(loadingManage.getId());
|
||||||
|
if (oldRecord != null) {
|
||||||
|
validateRunningImmutableTaskFields(oldRecord, loadingManage);
|
||||||
|
Set<Long> nextIds = new HashSet<>(waybillIds(loadingManage.getWaybillIdsJson()));
|
||||||
|
for (Long oldId : oldWaybillIds) {
|
||||||
|
if (oldId != null && !nextIds.contains(oldId) && hasLoadOrUnloadPunch(oldId)) {
|
||||||
|
throw new ServiceException("已打卡的子运单不可从进行中配载单移除");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
boolean result = saveOrUpdate(loadingManage);
|
boolean result = saveOrUpdate(loadingManage);
|
||||||
// 草稿仅预占运单号,不把运单业务状态改成 draft;正式确认时再完整同步为待执行
|
// 草稿仅预占运单号,不把运单业务状态改成 draft;正式确认时再完整同步为待执行
|
||||||
if (STATUS_DRAFT.equals(businessStatus)) {
|
if (STATUS_DRAFT.equals(businessStatus)) {
|
||||||
syncDraftWaybillReservation(loadingManage, oldWaybillIds);
|
syncDraftWaybillReservation(loadingManage, oldWaybillIds);
|
||||||
|
} else if (STATUS_RUNNING.equals(businessStatus)) {
|
||||||
|
// 进行中暂存:不重置原有子单状态/接单,仅同步任务信息与新增子单
|
||||||
|
List<Waybill> waybills = loadWaybills(waybillIds(loadingManage.getWaybillIdsJson()));
|
||||||
|
writeWaybillsForRunningEdit(loadingManage, oldWaybillIds, waybills);
|
||||||
} else {
|
} else {
|
||||||
syncAssociatedWaybills(loadingManage, businessStatus, oldWaybillIds);
|
syncAssociatedWaybills(loadingManage, businessStatus, oldWaybillIds);
|
||||||
}
|
}
|
||||||
@@ -156,28 +177,103 @@ public class LoadingManageServiceImpl extends BaseServiceImpl<LoadingManageMappe
|
|||||||
validate(loadingManage, false);
|
validate(loadingManage, false);
|
||||||
List<Long> oldWaybillIds = new ArrayList<>();
|
List<Long> oldWaybillIds = new ArrayList<>();
|
||||||
boolean ownChildrenAdmitted = false;
|
boolean ownChildrenAdmitted = false;
|
||||||
|
boolean runningEdit = false;
|
||||||
|
LoadingManage oldRecord = null;
|
||||||
if (Func.isNotEmpty(loadingManage.getId())) {
|
if (Func.isNotEmpty(loadingManage.getId())) {
|
||||||
LoadingManage oldRecord = loadEditable(loadingManage.getId(), true);
|
oldRecord = loadEditable(loadingManage.getId(), true);
|
||||||
oldWaybillIds = waybillIds(oldRecord.getWaybillIdsJson());
|
oldWaybillIds = waybillIds(oldRecord.getWaybillIdsJson());
|
||||||
// 草稿只预占运单号、未过判据,草稿转正式不得沿用本单豁免
|
// 草稿只预占运单号、未过判据,草稿转正式不得沿用本单豁免
|
||||||
ownChildrenAdmitted = !STATUS_DRAFT.equals(oldRecord.getBusinessStatus());
|
ownChildrenAdmitted = !STATUS_DRAFT.equals(oldRecord.getBusinessStatus());
|
||||||
|
runningEdit = STATUS_RUNNING.equals(oldRecord.getBusinessStatus());
|
||||||
loadingManage.setLoadingNo(oldRecord.getLoadingNo());
|
loadingManage.setLoadingNo(oldRecord.getLoadingNo());
|
||||||
loadingManage.setDeptId(oldRecord.getDeptId());
|
loadingManage.setDeptId(oldRecord.getDeptId());
|
||||||
loadingManage.setDeptName(oldRecord.getDeptName());
|
loadingManage.setDeptName(oldRecord.getDeptName());
|
||||||
}
|
}
|
||||||
prepareCreateOrUpdate(loadingManage);
|
prepareCreateOrUpdate(loadingManage);
|
||||||
// 确认提交:草稿/新建统一生成正式配载单(待执行)
|
// 进行中编辑:保持 running;草稿/新建确认后统一为待执行
|
||||||
loadingManage.setBusinessStatus(STATUS_PENDING);
|
loadingManage.setBusinessStatus(runningEdit ? STATUS_RUNNING : STATUS_PENDING);
|
||||||
if (Func.isEmpty(loadingManage.getLoadingNo())) {
|
if (Func.isEmpty(loadingManage.getLoadingNo())) {
|
||||||
loadingManage.setLoadingNo(nextCode());
|
loadingManage.setLoadingNo(nextCode());
|
||||||
}
|
}
|
||||||
List<Waybill> waybills = validateWaybillsAvailable(loadingManage, waybillIds(loadingManage.getWaybillIdsJson()), ownChildrenAdmitted);
|
List<Waybill> waybills = validateWaybillsAvailable(loadingManage, waybillIds(loadingManage.getWaybillIdsJson()), ownChildrenAdmitted);
|
||||||
validateCarrierContract(loadingManage, true, waybills);
|
validateCarrierContract(loadingManage, true, waybills);
|
||||||
|
if (runningEdit && oldRecord != null) {
|
||||||
|
validateRunningEdit(oldRecord, loadingManage, waybills, oldWaybillIds);
|
||||||
|
}
|
||||||
boolean result = saveOrUpdate(loadingManage);
|
boolean result = saveOrUpdate(loadingManage);
|
||||||
writeWaybillsForDriver(loadingManage, oldWaybillIds, waybills);
|
// 进行中编辑:保留原有子单状态与接单事实,仅对新加入子单做派车同步
|
||||||
|
if (runningEdit) {
|
||||||
|
writeWaybillsForRunningEdit(loadingManage, oldWaybillIds, waybills);
|
||||||
|
} else {
|
||||||
|
writeWaybillsForDriver(loadingManage, oldWaybillIds, waybills);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进行中配载编辑校验:必填任务字段不可改;已装/卸打卡的子运单不可移除。
|
||||||
|
*/
|
||||||
|
private void validateRunningEdit(LoadingManage oldRecord, LoadingManage incoming,
|
||||||
|
List<Waybill> waybills, List<Long> oldWaybillIds) {
|
||||||
|
validateRunningImmutableTaskFields(oldRecord, incoming);
|
||||||
|
Set<Long> nextIds = waybills.stream().map(Waybill::getId).filter(Objects::nonNull).collect(Collectors.toSet());
|
||||||
|
for (Long oldId : oldWaybillIds) {
|
||||||
|
if (oldId == null || nextIds.contains(oldId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (hasLoadOrUnloadPunch(oldId)) {
|
||||||
|
throw new ServiceException("已打卡的子运单不可从进行中配载单移除");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateRunningImmutableTaskFields(LoadingManage oldRecord, LoadingManage incoming) {
|
||||||
|
if (!Objects.equals(trimText(oldRecord.getCarrierType()), trimText(incoming.getCarrierType()))) {
|
||||||
|
throw new ServiceException("进行中配载单不允许修改承运类型");
|
||||||
|
}
|
||||||
|
if (Objects.equals(oldRecord.getCarrierType(), "承运商")
|
||||||
|
&& !Objects.equals(oldRecord.getCarrierContractId(), incoming.getCarrierContractId())) {
|
||||||
|
throw new ServiceException("进行中配载单不允许修改承运商");
|
||||||
|
}
|
||||||
|
if (!Objects.equals(trimText(oldRecord.getVehicleNo()), trimText(incoming.getVehicleNo()))) {
|
||||||
|
throw new ServiceException("进行中配载单不允许修改车牌号");
|
||||||
|
}
|
||||||
|
if (Objects.equals(oldRecord.getCarrierType(), CARRIER_SELF)) {
|
||||||
|
if (!Objects.equals(trimText(oldRecord.getDriverName()), trimText(incoming.getDriverName()))) {
|
||||||
|
throw new ServiceException("进行中配载单不允许修改司机");
|
||||||
|
}
|
||||||
|
if (!Objects.equals(trimText(oldRecord.getDriverPhone()), trimText(incoming.getDriverPhone()))) {
|
||||||
|
throw new ServiceException("进行中配载单不允许修改手机号");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasLoadOrUnloadPunch(Long waybillId) {
|
||||||
|
if (waybillId == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
List<WaybillNodePunch> punches = waybillNodePunchMapper.selectList(Wrappers.<WaybillNodePunch>lambdaQuery()
|
||||||
|
.eq(WaybillNodePunch::getWaybillId, waybillId)
|
||||||
|
.eq(WaybillNodePunch::getIsDeleted, 0));
|
||||||
|
return punches.stream().anyMatch(this::isLoadOrUnloadPunch);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isLoadOrUnloadPunch(WaybillNodePunch punch) {
|
||||||
|
if (punch == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String code = Func.toStr(punch.getNodeCode(), "").trim().toLowerCase();
|
||||||
|
String name = Func.toStr(punch.getNodeName(), "").trim();
|
||||||
|
return "load".equals(code) || name.contains("装货")
|
||||||
|
|| "unload".equals(code) || name.contains("卸货")
|
||||||
|
|| "arrival".equals(code) || name.contains("到货")
|
||||||
|
|| "sign".equals(code) || name.contains("签收");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String trimText(String value) {
|
||||||
|
return Func.toStr(value, "").trim();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void createFromImportedWaybills(String loadingNo, List<Waybill> waybills) {
|
public void createFromImportedWaybills(String loadingNo, List<Waybill> waybills) {
|
||||||
@@ -910,6 +1006,87 @@ public class LoadingManageServiceImpl extends BaseServiceImpl<LoadingManageMappe
|
|||||||
clearAssociatedWaybillAcceptRecords(loadingManage);
|
clearAssociatedWaybillAcceptRecords(loadingManage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进行中配载编辑同步:原有子单只更新任务可选信息,保留业务状态与接单事实;
|
||||||
|
* 新加入子单按正常派车逻辑推导状态并清接单;被移除且未打卡的子单释放回待执行。
|
||||||
|
*/
|
||||||
|
private void writeWaybillsForRunningEdit(LoadingManage loadingManage, List<Long> oldWaybillIds, List<Waybill> waybills) {
|
||||||
|
List<Long> newWaybillIds = waybillIds(loadingManage.getWaybillIdsJson());
|
||||||
|
Set<Long> oldIdSet = new HashSet<>(oldWaybillIds);
|
||||||
|
List<Long> removedIds = oldWaybillIds.stream()
|
||||||
|
.filter(id -> id != null && !newWaybillIds.contains(id))
|
||||||
|
.toList();
|
||||||
|
releaseAssociatedWaybills(removedIds, STATUS_PENDING);
|
||||||
|
List<Long> keptIds = newWaybillIds.stream()
|
||||||
|
.filter(oldIdSet::contains)
|
||||||
|
.toList();
|
||||||
|
if (Func.isNotEmpty(keptIds)) {
|
||||||
|
updateAssociatedWaybillTaskFields(loadingManage, keptIds, null);
|
||||||
|
}
|
||||||
|
List<Long> addedIds = newWaybillIds.stream()
|
||||||
|
.filter(id -> id != null && !oldIdSet.contains(id))
|
||||||
|
.toList();
|
||||||
|
if (Func.isEmpty(addedIds)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<Waybill> addedWaybills = waybills.stream()
|
||||||
|
.filter(waybill -> waybill.getId() != null && addedIds.contains(waybill.getId()))
|
||||||
|
.toList();
|
||||||
|
Map<Long, String> statusByWaybillId = deriveWaybillBusinessStatuses(addedWaybills);
|
||||||
|
Map<String, List<Long>> waybillIdsByStatus = new LinkedHashMap<>();
|
||||||
|
for (Long waybillId : addedIds) {
|
||||||
|
waybillIdsByStatus
|
||||||
|
.computeIfAbsent(statusByWaybillId.getOrDefault(waybillId, STATUS_PENDING), key -> new ArrayList<>())
|
||||||
|
.add(waybillId);
|
||||||
|
}
|
||||||
|
waybillIdsByStatus.forEach((status, ids) -> updateAssociatedWaybillFields(loadingManage, ids, status));
|
||||||
|
clearWaybillAcceptRecords(addedIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateAssociatedWaybillTaskFields(LoadingManage loadingManage, List<Long> waybillIds, String status) {
|
||||||
|
if (Func.isEmpty(waybillIds)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var update = Wrappers.<Waybill>lambdaUpdate()
|
||||||
|
.in(Waybill::getId, waybillIds)
|
||||||
|
.set(Waybill::getLoadingNo, loadingManage.getLoadingNo())
|
||||||
|
.set(Waybill::getCarrierType, loadingManage.getCarrierType())
|
||||||
|
.set(Waybill::getCarrierContractId, loadingManage.getCarrierContractId())
|
||||||
|
.set(Waybill::getCarrierName, loadingManage.getCarrierName())
|
||||||
|
.set(Waybill::getDriverName, loadingManage.getDriverName())
|
||||||
|
.set(Waybill::getDriverPhone, loadingManage.getDriverPhone())
|
||||||
|
.set(Waybill::getVehicleNo, loadingManage.getVehicleNo())
|
||||||
|
.set(Waybill::getTrailerVehicleNo, loadingManage.getTrailerVehicleNo())
|
||||||
|
.set(Waybill::getEscortName, loadingManage.getEscortName())
|
||||||
|
.set(Waybill::getEscortPhone, loadingManage.getEscortPhone())
|
||||||
|
.set(Waybill::getMileage, loadingManage.getMileage())
|
||||||
|
.set(Waybill::getEstimatedStartTime, toDateTime(loadingManage.getEstimatedStartDate()))
|
||||||
|
.set(Waybill::getEstimatedEndTime, toDateTime(loadingManage.getEstimatedEndDate()))
|
||||||
|
.set(Waybill::getTaskRemark, loadingManage.getTaskRemark())
|
||||||
|
.set(Waybill::getTaskInfoJson, loadingManage.getTaskInfoJson())
|
||||||
|
.set(Waybill::getCurrentProcessNode, loadingManage.getCurrentProcessNode());
|
||||||
|
if (Func.isNotEmpty(status)) {
|
||||||
|
update.set(Waybill::getBusinessStatus, status);
|
||||||
|
if (STATUS_COMPLETED.equals(status)) {
|
||||||
|
update.set(Waybill::getEndDate, LocalDate.now());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
waybillMapper.update(null, update);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearWaybillAcceptRecords(List<Long> waybillIds) {
|
||||||
|
if (Func.isEmpty(waybillIds)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
waybillMapper.update(null, Wrappers.<Waybill>lambdaUpdate()
|
||||||
|
.in(Waybill::getId, waybillIds)
|
||||||
|
.set(Waybill::getDriverAcceptStatus, WaybillProcessSupport.ACCEPT_PENDING)
|
||||||
|
.set(Waybill::getDriverAcceptTime, null)
|
||||||
|
.set(Waybill::getDriverAcceptDriverId, null)
|
||||||
|
.set(Waybill::getDriverRejectTime, null)
|
||||||
|
.set(Waybill::getDriverRejectReason, null));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 子运单业务状态逐张按各自项目的实时过程配置推导:需要接单 → 待执行,不需要 → 进行中。
|
* 子运单业务状态逐张按各自项目的实时过程配置推导:需要接单 → 待执行,不需要 → 进行中。
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
+1
-1
@@ -1069,7 +1069,7 @@ public class ManageWaybillServiceImpl implements IManageWaybillService {
|
|||||||
return switch (businessStatus) {
|
return switch (businessStatus) {
|
||||||
case STATUS_PENDING, "waiting_dispatch", "dispatching" -> 0;
|
case STATUS_PENDING, "waiting_dispatch", "dispatching" -> 0;
|
||||||
case STATUS_RUNNING -> 1;
|
case STATUS_RUNNING -> 1;
|
||||||
case STATUS_COMPLETED -> 2;
|
case WaybillProcessSupport.STATUS_PENDING_RETURN, STATUS_COMPLETED -> 2;
|
||||||
case STATUS_CANCELLED -> 3;
|
case STATUS_CANCELLED -> 3;
|
||||||
default -> null;
|
default -> null;
|
||||||
};
|
};
|
||||||
|
|||||||
-45
@@ -2563,44 +2563,11 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl<PaymentApplic
|
|||||||
private void validateBill(BillLedger ledger, Long deptId, BigDecimal amount, boolean checkMaturity,
|
private void validateBill(BillLedger ledger, Long deptId, BigDecimal amount, boolean checkMaturity,
|
||||||
Long paymentApplicationId, Long settlementId, Long preSettlementId) {
|
Long paymentApplicationId, Long settlementId, Long preSettlementId) {
|
||||||
if (ledger == null || Objects.equals(ledger.getIsDeleted(), 1)) throw new ServiceException("所选汇票台账不存在");
|
if (ledger == null || Objects.equals(ledger.getIsDeleted(), 1)) throw new ServiceException("所选汇票台账不存在");
|
||||||
boolean partyMatched = settlementPartiesMatch(ledger, settlementId, preSettlementId);
|
|
||||||
if (!"received".equals(ledger.getBillType()) && !partyMatched) {
|
|
||||||
throw new ServiceException("汇票付款仅可选择收票类型的汇票,或出票单位与收票单位均为当前结算收付款方的汇票");
|
|
||||||
}
|
|
||||||
if (checkMaturity && (ledger.getMaturityDate() == null || ledger.getMaturityDate().isBefore(LocalDate.now()))) {
|
if (checkMaturity && (ledger.getMaturityDate() == null || ledger.getMaturityDate().isBefore(LocalDate.now()))) {
|
||||||
throw new ServiceException("所选汇票已到期");
|
throw new ServiceException("所选汇票已到期");
|
||||||
}
|
}
|
||||||
BigDecimal available = money(ledger.getAvailableBalance()).add(occupiedAmount(paymentApplicationId, ledger.getId()));
|
BigDecimal available = money(ledger.getAvailableBalance()).add(occupiedAmount(paymentApplicationId, ledger.getId()));
|
||||||
if (money(amount).compareTo(available) > 0) throw new ServiceException("申请付款金额超过汇票可用余额");
|
if (money(amount).compareTo(available) > 0) throw new ServiceException("申请付款金额超过汇票可用余额");
|
||||||
if (!partyMatched && !departmentAvailable(ledger, deptId)) throw new ServiceException("当前使用部门不在汇票可用部门范围内");
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 出票单位、收票单位与结算付款方、收款方一致(顺序不限) */
|
|
||||||
private boolean settlementPartiesMatch(BillLedger ledger, Long settlementId, Long preSettlementId) {
|
|
||||||
String payerName = null;
|
|
||||||
String payeeName = null;
|
|
||||||
if (settlementId != null) {
|
|
||||||
FormalSettlement settlement = formalSettlementMapper.selectById(settlementId);
|
|
||||||
if (settlement != null && !Objects.equals(settlement.getIsDeleted(), 1)) {
|
|
||||||
payerName = settlement.getPayerName();
|
|
||||||
payeeName = settlement.getPayeeName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((payerName == null || payeeName == null) && preSettlementId != null) {
|
|
||||||
PreSettlement settlement = preSettlementMapper.selectById(preSettlementId);
|
|
||||||
if (settlement != null && !Objects.equals(settlement.getIsDeleted(), 1)) {
|
|
||||||
payerName = settlement.getPayerName();
|
|
||||||
payeeName = settlement.getPayeeName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String issuer = ledger.getIssuerName() == null ? "" : ledger.getIssuerName().trim();
|
|
||||||
String receiver = ledger.getReceiverName() == null ? "" : ledger.getReceiverName().trim();
|
|
||||||
String payer = payerName == null ? "" : payerName.trim();
|
|
||||||
String payee = payeeName == null ? "" : payeeName.trim();
|
|
||||||
if (issuer.isEmpty() || receiver.isEmpty() || payer.isEmpty() || payee.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return (issuer.equals(payer) && receiver.equals(payee)) || (issuer.equals(payee) && receiver.equals(payer));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void useBillBalance(PaymentApplication entity) {
|
private void useBillBalance(PaymentApplication entity) {
|
||||||
@@ -2756,18 +2723,6 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl<PaymentApplic
|
|||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean departmentAvailable(BillLedger ledger, Long deptId) {
|
|
||||||
if (Func.isEmpty(ledger.getAvailableDeptIdsJson())) return false;
|
|
||||||
try {
|
|
||||||
Object parsed = JsonUtil.parse(ledger.getAvailableDeptIdsJson(), List.class);
|
|
||||||
if (!(parsed instanceof List<?> values)) return false;
|
|
||||||
if (values.stream().anyMatch(value -> "all".equals(String.valueOf(value)))) return true;
|
|
||||||
return deptId != null && values.stream().anyMatch(value -> String.valueOf(deptId).equals(String.valueOf(value)));
|
|
||||||
} catch (Exception exception) {
|
|
||||||
throw new ServiceException("汇票可用部门配置不正确");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isBillPayment(String paymentMethod) {
|
public boolean isBillPayment(String paymentMethod) {
|
||||||
if (Func.isEmpty(paymentMethod)) return false;
|
if (Func.isEmpty(paymentMethod)) return false;
|
||||||
|
|||||||
+45
-3
@@ -34,6 +34,7 @@ import org.springblade.core.tenant.annotation.TenantIgnore;
|
|||||||
import org.springblade.core.tool.jackson.JsonUtil;
|
import org.springblade.core.tool.jackson.JsonUtil;
|
||||||
import org.springblade.core.tool.utils.BeanUtil;
|
import org.springblade.core.tool.utils.BeanUtil;
|
||||||
import org.springblade.core.tool.utils.Func;
|
import org.springblade.core.tool.utils.Func;
|
||||||
|
import org.springblade.system.cache.SysCache;
|
||||||
import org.springblade.system.cache.UserCache;
|
import org.springblade.system.cache.UserCache;
|
||||||
import org.springblade.system.pojo.entity.Dept;
|
import org.springblade.system.pojo.entity.Dept;
|
||||||
import org.springblade.transport.excel.ProjectApplyExcel;
|
import org.springblade.transport.excel.ProjectApplyExcel;
|
||||||
@@ -488,8 +489,7 @@ public class ProjectApplyServiceImpl extends BaseServiceImpl<ProjectApplyMapper,
|
|||||||
projectApply.setUndertakeDeptName(dept.getDeptName());
|
projectApply.setUndertakeDeptName(dept.getDeptName());
|
||||||
}
|
}
|
||||||
if (Func.isEmpty(projectApply.getBusinessDeptId())) {
|
if (Func.isEmpty(projectApply.getBusinessDeptId())) {
|
||||||
projectApply.setBusinessDeptId(firstUndertakeDeptId(projectApply.getUndertakeDeptId()));
|
fillDefaultBusinessDept(projectApply);
|
||||||
projectApply.setBusinessDeptName(firstUndertakeDeptName(projectApply.getUndertakeDeptName()));
|
|
||||||
}
|
}
|
||||||
if (Func.isEmpty(projectApply.getHandlerUserId())) {
|
if (Func.isEmpty(projectApply.getHandlerUserId())) {
|
||||||
projectApply.setHandlerUserId(AuthUtil.getUserId());
|
projectApply.setHandlerUserId(AuthUtil.getUserId());
|
||||||
@@ -748,7 +748,7 @@ public class ProjectApplyServiceImpl extends BaseServiceImpl<ProjectApplyMapper,
|
|||||||
private void validateSubmit(ProjectApply projectApply) {
|
private void validateSubmit(ProjectApply projectApply) {
|
||||||
validateDraft(projectApply);
|
validateDraft(projectApply);
|
||||||
TransportBusinessSupport.validateRequired(projectApply.getProjectShortName(), "请输入项目简称");
|
TransportBusinessSupport.validateRequired(projectApply.getProjectShortName(), "请输入项目简称");
|
||||||
TransportBusinessSupport.validateRequired(projectApply.getBusinessDeptName(), "请选择业务部门");
|
validateBusinessDept(projectApply);
|
||||||
TransportBusinessSupport.validateRequired(projectApply.getUndertakeDeptName(), "请选择平台公司");
|
TransportBusinessSupport.validateRequired(projectApply.getUndertakeDeptName(), "请选择平台公司");
|
||||||
TransportBusinessSupport.validateRequired(projectApply.getBusinessMode(), "请选择业务模式");
|
TransportBusinessSupport.validateRequired(projectApply.getBusinessMode(), "请选择业务模式");
|
||||||
TransportBusinessSupport.validateRequired(projectApply.getCustomerNames(), "请选择客户");
|
TransportBusinessSupport.validateRequired(projectApply.getCustomerNames(), "请选择客户");
|
||||||
@@ -1066,6 +1066,48 @@ public class ProjectApplyServiceImpl extends BaseServiceImpl<ProjectApplyMapper,
|
|||||||
return exception;
|
return exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增时默认业务部门:取当前用户所属部门中第一个「是否业务部门=是」的组织。
|
||||||
|
*/
|
||||||
|
private void fillDefaultBusinessDept(ProjectApply projectApply) {
|
||||||
|
List<Long> deptIds = Func.toLongList(AuthUtil.getDeptId());
|
||||||
|
if (Func.isEmpty(deptIds)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (Long deptId : deptIds) {
|
||||||
|
if (Func.isEmpty(deptId) || deptId <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Dept dept = SysCache.getDept(deptId);
|
||||||
|
if (dept != null && Objects.equals(dept.getIsBusinessDept(), 1)) {
|
||||||
|
projectApply.setBusinessDeptId(dept.getId());
|
||||||
|
projectApply.setBusinessDeptName(dept.getDeptName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验业务部门必须是组织中标记为「是否业务部门=是」的部门。
|
||||||
|
*/
|
||||||
|
private void validateBusinessDept(ProjectApply projectApply) {
|
||||||
|
Long businessDeptId = projectApply.getBusinessDeptId();
|
||||||
|
if (Func.isEmpty(businessDeptId)) {
|
||||||
|
throw new ServiceException("请选择业务部门");
|
||||||
|
}
|
||||||
|
Dept dept = SysCache.getDept(businessDeptId);
|
||||||
|
if (dept == null || Objects.equals(dept.getIsDeleted(), 1)) {
|
||||||
|
throw new ServiceException("业务部门不存在");
|
||||||
|
}
|
||||||
|
if (!Objects.equals(dept.getIsBusinessDept(), 1)) {
|
||||||
|
throw new ServiceException("请选择组织中标记为业务部门的部门");
|
||||||
|
}
|
||||||
|
if (Func.isNotEmpty(dept.getDeptName())) {
|
||||||
|
projectApply.setBusinessDeptName(dept.getDeptName());
|
||||||
|
}
|
||||||
|
TransportBusinessSupport.validateRequired(projectApply.getBusinessDeptName(), "请选择业务部门");
|
||||||
|
}
|
||||||
|
|
||||||
private void normalizeUndertakeDept(ProjectApply projectApply) {
|
private void normalizeUndertakeDept(ProjectApply projectApply) {
|
||||||
if (projectApply == null) {
|
if (projectApply == null) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
+1
@@ -3295,6 +3295,7 @@ public class ReceivablePayableDetailServiceImpl
|
|||||||
private String waybillStatusName(String status) {
|
private String waybillStatusName(String status) {
|
||||||
return switch (status == null ? "" : status) {
|
return switch (status == null ? "" : status) {
|
||||||
case "completed" -> "已完成";
|
case "completed" -> "已完成";
|
||||||
|
case "pending_return" -> "待确认回单";
|
||||||
case "processing", "running", "in_progress", "inProgress" -> "进行中";
|
case "processing", "running", "in_progress", "inProgress" -> "进行中";
|
||||||
case "pending", "created" -> "待执行";
|
case "pending", "created" -> "待执行";
|
||||||
case "cancelled", "canceled" -> "已取消";
|
case "cancelled", "canceled" -> "已取消";
|
||||||
|
|||||||
+14
-1
@@ -967,6 +967,7 @@ public class WaybillServiceImpl extends BaseServiceImpl<WaybillMapper, Waybill>
|
|||||||
*/
|
*/
|
||||||
private static boolean passedAcceptStage(String businessStatus) {
|
private static boolean passedAcceptStage(String businessStatus) {
|
||||||
return "running".equals(businessStatus)
|
return "running".equals(businessStatus)
|
||||||
|
|| WaybillProcessSupport.STATUS_PENDING_RETURN.equals(businessStatus)
|
||||||
|| "completed".equals(businessStatus)
|
|| "completed".equals(businessStatus)
|
||||||
|| "cancelled".equals(businessStatus);
|
|| "cancelled".equals(businessStatus);
|
||||||
}
|
}
|
||||||
@@ -1507,6 +1508,13 @@ public class WaybillServiceImpl extends BaseServiceImpl<WaybillMapper, Waybill>
|
|||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public boolean confirmReturnReceipt(Long id) {
|
public boolean confirmReturnReceipt(Long id) {
|
||||||
Waybill waybill = loadEditable(id, true);
|
Waybill waybill = loadEditable(id, true);
|
||||||
|
String status = waybill.getBusinessStatus();
|
||||||
|
// pending_return 为正规待确认态;running/processing 兼容历史「打完卡仍停在进行中」的数据
|
||||||
|
if (!WaybillProcessSupport.STATUS_PENDING_RETURN.equals(status)
|
||||||
|
&& !"running".equals(status)
|
||||||
|
&& !"processing".equals(status)) {
|
||||||
|
throw new ServiceException("当前状态不允许确认回单");
|
||||||
|
}
|
||||||
String processJson = LiveProcessConfigSupport.resolve(
|
String processJson = LiveProcessConfigSupport.resolve(
|
||||||
LiveProcessConfigSupport.byProject(processConfigService, waybill.getProjectId()),
|
LiveProcessConfigSupport.byProject(processConfigService, waybill.getProjectId()),
|
||||||
waybill.getProcessJson());
|
waybill.getProcessJson());
|
||||||
@@ -1585,7 +1593,12 @@ public class WaybillServiceImpl extends BaseServiceImpl<WaybillMapper, Waybill>
|
|||||||
BusinessRemoveResultVO result = new BusinessRemoveResultVO();
|
BusinessRemoveResultVO result = new BusinessRemoveResultVO();
|
||||||
for (Waybill waybill : listByIds(idList)) {
|
for (Waybill waybill : listByIds(idList)) {
|
||||||
try {
|
try {
|
||||||
complete(waybill.getId());
|
// 待确认回单走确认回单校验(打卡节点 + 未了结异常);其它状态仍走普通完成
|
||||||
|
if (WaybillProcessSupport.STATUS_PENDING_RETURN.equals(waybill.getBusinessStatus())) {
|
||||||
|
confirmReturnReceipt(waybill.getId());
|
||||||
|
} else {
|
||||||
|
complete(waybill.getId());
|
||||||
|
}
|
||||||
result.setSuccessCount(result.getSuccessCount() + 1);
|
result.setSuccessCount(result.getSuccessCount() + 1);
|
||||||
} catch (Exception exception) {
|
} catch (Exception exception) {
|
||||||
log.error("批量完成运单失败,waybillId:{}, waybillNo:{}, failureReason:{}",
|
log.error("批量完成运单失败,waybillId:{}, waybillNo:{}, failureReason:{}",
|
||||||
|
|||||||
+14
-5
@@ -49,6 +49,8 @@ public final class WaybillProcessSupport {
|
|||||||
|
|
||||||
public static final String STATUS_PENDING = "pending";
|
public static final String STATUS_PENDING = "pending";
|
||||||
public static final String STATUS_RUNNING = "running";
|
public static final String STATUS_RUNNING = "running";
|
||||||
|
/** 司机打卡已完成、待运管员确认回单 */
|
||||||
|
public static final String STATUS_PENDING_RETURN = "pending_return";
|
||||||
public static final String ACCEPT_PENDING = "pending";
|
public static final String ACCEPT_PENDING = "pending";
|
||||||
public static final String ACCEPT_ACCEPTED = "accepted";
|
public static final String ACCEPT_ACCEPTED = "accepted";
|
||||||
public static final String ACCEPT_REJECTED = "rejected";
|
public static final String ACCEPT_REJECTED = "rejected";
|
||||||
@@ -134,14 +136,17 @@ public final class WaybillProcessSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 运单已结束:已完成或已取消。此后不再接受司机打卡。
|
* 运单已结束:已完成、已取消,或待确认回单。此后不再接受司机打卡。
|
||||||
* <p>
|
* <p>
|
||||||
* 只认这两个状态,大小写不敏感。草稿、待执行、待调度、调度中的运单司机仍要能打卡,
|
* 待确认回单表示司机侧节点已打完,等待运管确认,不能再打卡。
|
||||||
|
* 草稿、待执行、待调度、调度中的运单司机仍要能打卡,
|
||||||
* 所以不能按 {@link #isTerminalBusinessStatus} 的「终态或调度中间态」口径判定。
|
* 所以不能按 {@link #isTerminalBusinessStatus} 的「终态或调度中间态」口径判定。
|
||||||
*/
|
*/
|
||||||
public static boolean isPunchEnded(String businessStatus) {
|
public static boolean isPunchEnded(String businessStatus) {
|
||||||
String status = stringVal(businessStatus);
|
String status = stringVal(businessStatus);
|
||||||
return "completed".equalsIgnoreCase(status) || "cancelled".equalsIgnoreCase(status);
|
return "completed".equalsIgnoreCase(status)
|
||||||
|
|| "cancelled".equalsIgnoreCase(status)
|
||||||
|
|| STATUS_PENDING_RETURN.equalsIgnoreCase(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -155,6 +160,9 @@ public final class WaybillProcessSupport {
|
|||||||
if ("cancelled".equalsIgnoreCase(status)) {
|
if ("cancelled".equalsIgnoreCase(status)) {
|
||||||
return "运单已取消";
|
return "运单已取消";
|
||||||
}
|
}
|
||||||
|
if (STATUS_PENDING_RETURN.equalsIgnoreCase(status)) {
|
||||||
|
return "运单待确认回单";
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +221,8 @@ public final class WaybillProcessSupport {
|
|||||||
|| "completed".equals(businessStatus)
|
|| "completed".equals(businessStatus)
|
||||||
|| "cancelled".equals(businessStatus)
|
|| "cancelled".equals(businessStatus)
|
||||||
|| "waiting_dispatch".equals(businessStatus)
|
|| "waiting_dispatch".equals(businessStatus)
|
||||||
|| "dispatching".equals(businessStatus);
|
|| "dispatching".equals(businessStatus)
|
||||||
|
|| STATUS_PENDING_RETURN.equals(businessStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -221,7 +230,7 @@ public final class WaybillProcessSupport {
|
|||||||
* <p>
|
* <p>
|
||||||
* 需要接单(接单节点 confirmMode=yes)且尚未接单(未响应 / 已拒绝)→ pending(待执行);
|
* 需要接单(接单节点 confirmMode=yes)且尚未接单(未响应 / 已拒绝)→ pending(待执行);
|
||||||
* 已接单 → running(进行中);不需要接单 → running(仅当当前为空或 pending 时提升)。
|
* 已接单 → running(进行中);不需要接单 → running(仅当当前为空或 pending 时提升)。
|
||||||
* draft / completed / cancelled 等终态或调度中间态不改动。
|
* draft / completed / cancelled / pending_return 等终态或调度中间态不改动。
|
||||||
*/
|
*/
|
||||||
public static String normalizeBusinessStatus(String businessStatus, String processJson) {
|
public static String normalizeBusinessStatus(String businessStatus, String processJson) {
|
||||||
return normalizeBusinessStatus(businessStatus, processJson, null);
|
return normalizeBusinessStatus(businessStatus, processJson, null);
|
||||||
|
|||||||
+1
@@ -122,6 +122,7 @@ public class WaybillWrapper extends BaseEntityWrapper<Waybill, WaybillVO> {
|
|||||||
case "waiting_dispatch" -> "待调度";
|
case "waiting_dispatch" -> "待调度";
|
||||||
case "dispatching" -> "调度中";
|
case "dispatching" -> "调度中";
|
||||||
case "running", "processing", "in_progress", "inProgress" -> "进行中";
|
case "running", "processing", "in_progress", "inProgress" -> "进行中";
|
||||||
|
case "pending_return" -> "待确认回单";
|
||||||
case "completed" -> "已完成";
|
case "completed" -> "已完成";
|
||||||
case "cancelled" -> "已取消";
|
case "cancelled" -> "已取消";
|
||||||
case "closed" -> "已关闭";
|
case "closed" -> "已关闭";
|
||||||
|
|||||||
+5
-2
@@ -337,12 +337,14 @@ class WaybillProcessSupportTest {
|
|||||||
// ------------------------------------------------------------ 结束门禁
|
// ------------------------------------------------------------ 结束门禁
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("结束门禁:只认已完成与已取消,大小写不敏感")
|
@DisplayName("结束门禁:已完成、已取消、待确认回单,大小写不敏感")
|
||||||
void punchEndedOnlyForCompletedAndCancelled() {
|
void punchEndedOnlyForCompletedAndCancelled() {
|
||||||
assertTrue(WaybillProcessSupport.isPunchEnded("completed"));
|
assertTrue(WaybillProcessSupport.isPunchEnded("completed"));
|
||||||
assertTrue(WaybillProcessSupport.isPunchEnded("COMPLETED"));
|
assertTrue(WaybillProcessSupport.isPunchEnded("COMPLETED"));
|
||||||
assertTrue(WaybillProcessSupport.isPunchEnded("cancelled"));
|
assertTrue(WaybillProcessSupport.isPunchEnded("cancelled"));
|
||||||
assertTrue(WaybillProcessSupport.isPunchEnded("Cancelled"));
|
assertTrue(WaybillProcessSupport.isPunchEnded("Cancelled"));
|
||||||
|
assertTrue(WaybillProcessSupport.isPunchEnded("pending_return"));
|
||||||
|
assertTrue(WaybillProcessSupport.isPunchEnded("PENDING_RETURN"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -358,11 +360,12 @@ class WaybillProcessSupportTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("结束门禁文案:完成与取消各一句,非结束态没有文案")
|
@DisplayName("结束门禁文案:完成、取消、待确认回单各一句,非结束态没有文案")
|
||||||
void punchEndedReasonOnlyForEndedStatuses() {
|
void punchEndedReasonOnlyForEndedStatuses() {
|
||||||
assertEquals("运单已完成", WaybillProcessSupport.punchEndedReason("completed"));
|
assertEquals("运单已完成", WaybillProcessSupport.punchEndedReason("completed"));
|
||||||
assertEquals("运单已完成", WaybillProcessSupport.punchEndedReason(" COMPLETED "));
|
assertEquals("运单已完成", WaybillProcessSupport.punchEndedReason(" COMPLETED "));
|
||||||
assertEquals("运单已取消", WaybillProcessSupport.punchEndedReason("cancelled"));
|
assertEquals("运单已取消", WaybillProcessSupport.punchEndedReason("cancelled"));
|
||||||
|
assertEquals("运单待确认回单", WaybillProcessSupport.punchEndedReason("pending_return"));
|
||||||
assertNull(WaybillProcessSupport.punchEndedReason(null));
|
assertNull(WaybillProcessSupport.punchEndedReason(null));
|
||||||
assertNull(WaybillProcessSupport.punchEndedReason(""));
|
assertNull(WaybillProcessSupport.punchEndedReason(""));
|
||||||
assertNull(WaybillProcessSupport.punchEndedReason(" "));
|
assertNull(WaybillProcessSupport.punchEndedReason(" "));
|
||||||
|
|||||||
@@ -311,6 +311,7 @@ CREATE TABLE `blade_dept` (
|
|||||||
`mnemonic_code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '助记码',
|
`mnemonic_code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '助记码',
|
||||||
`carrier_customer_id` bigint NULL DEFAULT NULL COMMENT '承运商客商档案主键',
|
`carrier_customer_id` bigint NULL DEFAULT NULL COMMENT '承运商客商档案主键',
|
||||||
`is_platform_company` tinyint NOT NULL DEFAULT 0 COMMENT '是否平台公司:0否,1是',
|
`is_platform_company` tinyint NOT NULL DEFAULT 0 COMMENT '是否平台公司:0否,1是',
|
||||||
|
`is_business_dept` tinyint NOT NULL DEFAULT 0 COMMENT '是否业务部门:0否,1是',
|
||||||
`oa_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'OA主键',
|
`oa_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'OA主键',
|
||||||
`oa_sup_sub_com_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'OA上级主键',
|
`oa_sup_sub_com_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'OA上级主键',
|
||||||
`sort` int NULL DEFAULT NULL COMMENT '排序',
|
`sort` int NULL DEFAULT NULL COMMENT '排序',
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
-- 机构表:新增「是否业务部门」字段,默认否
|
||||||
|
-- 全量 OA 同步时须保留本地已配置值,不得覆盖
|
||||||
|
|
||||||
|
ALTER TABLE `blade_dept`
|
||||||
|
ADD COLUMN `is_business_dept` tinyint NOT NULL DEFAULT 0 COMMENT '是否业务部门:0否,1是' AFTER `is_platform_company`;
|
||||||
@@ -7,8 +7,12 @@
|
|||||||
-- 3. 只统计各功能列表对应的主表。随主单保存的明细、联系人、附件、变更流水不重复计数。
|
-- 3. 只统计各功能列表对应的主表。随主单保存的明细、联系人、附件、变更流水不重复计数。
|
||||||
-- 4. 含已逻辑删除的数据,因为这些记录确实被创建过。
|
-- 4. 含已逻辑删除的数据,因为这些记录确实被创建过。
|
||||||
-- 5. 客商档案菜单挂在「车/船务管理」下,这里按统计口径单独计入「客商管理」。
|
-- 5. 客商档案菜单挂在「车/船务管理」下,这里按统计口径单独计入「客商管理」。
|
||||||
-- 6. 未纳入:结算管理、首付款管理、在途管理,以及系统管理下的开票项目。
|
-- 6. 未纳入:在途管理,以及系统管理下的开票项目。
|
||||||
-- 7. 导入运单产生的运单计入「业务模块-运单管理」,不另计导入批次。
|
-- 7. 导入运单产生的运单计入「业务模块-运单管理」,不另计导入批次。
|
||||||
|
-- 导入结算单产生的正式结算单计入「结算管理」的付款结算单或收款结算单,不另计导入批次。
|
||||||
|
-- 8. 付款结算单、收款结算单共用 blade_formal_settlement,按 settlement_type 区分(payable/receivable)。
|
||||||
|
-- 应收、应付共用 blade_receivable_payable_detail,同样按 settlement_type 区分。
|
||||||
|
-- 9. 菜单名称为「收付款管理」,统计模块名与菜单一致。
|
||||||
|
|
||||||
SET NAMES utf8mb4;
|
SET NAMES utf8mb4;
|
||||||
|
|
||||||
@@ -396,7 +400,124 @@ SELECT t.create_user, 8, '运力模块', 4, '车辆调度', 'blade_transport_veh
|
|||||||
FROM blade_transport_vehicle_dispatch t
|
FROM blade_transport_vehicle_dispatch t
|
||||||
INNER JOIN tmp_stat_user u ON u.id = t.create_user
|
INNER JOIN tmp_stat_user u ON u.id = t.create_user
|
||||||
WHERE t.create_time >= @stat_start AND t.create_time < @stat_end_exclusive
|
WHERE t.create_time >= @stat_start AND t.create_time < @stat_end_exclusive
|
||||||
GROUP BY t.create_user;
|
GROUP BY t.create_user
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO tmp_stat_detail (create_user, module_sort, module_name, biz_sort, biz_name, table_name, cnt)
|
||||||
|
SELECT t.create_user, 9, '结算管理', 1, '应收', 'blade_receivable_payable_detail', COUNT(*)
|
||||||
|
FROM blade_receivable_payable_detail t
|
||||||
|
INNER JOIN tmp_stat_user u ON u.id = t.create_user
|
||||||
|
WHERE t.create_time >= @stat_start AND t.create_time < @stat_end_exclusive
|
||||||
|
AND t.settlement_type = 'receivable'
|
||||||
|
GROUP BY t.create_user
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO tmp_stat_detail (create_user, module_sort, module_name, biz_sort, biz_name, table_name, cnt)
|
||||||
|
SELECT t.create_user, 9, '结算管理', 2, '应付', 'blade_receivable_payable_detail', COUNT(*)
|
||||||
|
FROM blade_receivable_payable_detail t
|
||||||
|
INNER JOIN tmp_stat_user u ON u.id = t.create_user
|
||||||
|
WHERE t.create_time >= @stat_start AND t.create_time < @stat_end_exclusive
|
||||||
|
AND t.settlement_type = 'payable'
|
||||||
|
GROUP BY t.create_user
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO tmp_stat_detail (create_user, module_sort, module_name, biz_sort, biz_name, table_name, cnt)
|
||||||
|
SELECT t.create_user, 9, '结算管理', 3, '预付结算单', 'blade_pre_settlement', COUNT(*)
|
||||||
|
FROM blade_pre_settlement t
|
||||||
|
INNER JOIN tmp_stat_user u ON u.id = t.create_user
|
||||||
|
WHERE t.create_time >= @stat_start AND t.create_time < @stat_end_exclusive
|
||||||
|
GROUP BY t.create_user
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO tmp_stat_detail (create_user, module_sort, module_name, biz_sort, biz_name, table_name, cnt)
|
||||||
|
SELECT t.create_user, 9, '结算管理', 4, '付款结算单', 'blade_formal_settlement', COUNT(*)
|
||||||
|
FROM blade_formal_settlement t
|
||||||
|
INNER JOIN tmp_stat_user u ON u.id = t.create_user
|
||||||
|
WHERE t.create_time >= @stat_start AND t.create_time < @stat_end_exclusive
|
||||||
|
AND t.settlement_type = 'payable'
|
||||||
|
GROUP BY t.create_user
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO tmp_stat_detail (create_user, module_sort, module_name, biz_sort, biz_name, table_name, cnt)
|
||||||
|
SELECT t.create_user, 9, '结算管理', 5, '收款结算单', 'blade_formal_settlement', COUNT(*)
|
||||||
|
FROM blade_formal_settlement t
|
||||||
|
INNER JOIN tmp_stat_user u ON u.id = t.create_user
|
||||||
|
WHERE t.create_time >= @stat_start AND t.create_time < @stat_end_exclusive
|
||||||
|
AND t.settlement_type = 'receivable'
|
||||||
|
GROUP BY t.create_user
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO tmp_stat_detail (create_user, module_sort, module_name, biz_sort, biz_name, table_name, cnt)
|
||||||
|
SELECT t.create_user, 9, '结算管理', 6, '运输对账', 'blade_transport_reconciliation', COUNT(*)
|
||||||
|
FROM blade_transport_reconciliation t
|
||||||
|
INNER JOIN tmp_stat_user u ON u.id = t.create_user
|
||||||
|
WHERE t.create_time >= @stat_start AND t.create_time < @stat_end_exclusive
|
||||||
|
GROUP BY t.create_user
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO tmp_stat_detail (create_user, module_sort, module_name, biz_sort, biz_name, table_name, cnt)
|
||||||
|
SELECT t.create_user, 9, '结算管理', 7, '结算调整单', 'blade_settlement_adjustment', COUNT(*)
|
||||||
|
FROM blade_settlement_adjustment t
|
||||||
|
INNER JOIN tmp_stat_user u ON u.id = t.create_user
|
||||||
|
WHERE t.create_time >= @stat_start AND t.create_time < @stat_end_exclusive
|
||||||
|
GROUP BY t.create_user
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO tmp_stat_detail (create_user, module_sort, module_name, biz_sort, biz_name, table_name, cnt)
|
||||||
|
SELECT t.create_user, 10, '收付款管理', 1, '付款管理', 'blade_payment_application', COUNT(*)
|
||||||
|
FROM blade_payment_application t
|
||||||
|
INNER JOIN tmp_stat_user u ON u.id = t.create_user
|
||||||
|
WHERE t.create_time >= @stat_start AND t.create_time < @stat_end_exclusive
|
||||||
|
GROUP BY t.create_user
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO tmp_stat_detail (create_user, module_sort, module_name, biz_sort, biz_name, table_name, cnt)
|
||||||
|
SELECT t.create_user, 10, '收付款管理', 2, '开票管理', 'blade_invoice_application', COUNT(*)
|
||||||
|
FROM blade_invoice_application t
|
||||||
|
INNER JOIN tmp_stat_user u ON u.id = t.create_user
|
||||||
|
WHERE t.create_time >= @stat_start AND t.create_time < @stat_end_exclusive
|
||||||
|
GROUP BY t.create_user
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO tmp_stat_detail (create_user, module_sort, module_name, biz_sort, biz_name, table_name, cnt)
|
||||||
|
SELECT t.create_user, 10, '收付款管理', 3, '收票管理', 'blade_invoice_receipt', COUNT(*)
|
||||||
|
FROM blade_invoice_receipt t
|
||||||
|
INNER JOIN tmp_stat_user u ON u.id = t.create_user
|
||||||
|
WHERE t.create_time >= @stat_start AND t.create_time < @stat_end_exclusive
|
||||||
|
GROUP BY t.create_user
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO tmp_stat_detail (create_user, module_sort, module_name, biz_sort, biz_name, table_name, cnt)
|
||||||
|
SELECT t.create_user, 10, '收付款管理', 4, '收款流水', 'blade_kingdee_receipt_flow', COUNT(*)
|
||||||
|
FROM blade_kingdee_receipt_flow t
|
||||||
|
INNER JOIN tmp_stat_user u ON u.id = t.create_user
|
||||||
|
WHERE t.create_time >= @stat_start AND t.create_time < @stat_end_exclusive
|
||||||
|
GROUP BY t.create_user
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO tmp_stat_detail (create_user, module_sort, module_name, biz_sort, biz_name, table_name, cnt)
|
||||||
|
SELECT t.create_user, 10, '收付款管理', 5, '认领记录', 'blade_receipt_claim', COUNT(*)
|
||||||
|
FROM blade_receipt_claim t
|
||||||
|
INNER JOIN tmp_stat_user u ON u.id = t.create_user
|
||||||
|
WHERE t.create_time >= @stat_start AND t.create_time < @stat_end_exclusive
|
||||||
|
GROUP BY t.create_user
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO tmp_stat_detail (create_user, module_sort, module_name, biz_sort, biz_name, table_name, cnt)
|
||||||
|
SELECT t.create_user, 10, '收付款管理', 6, '汇票台账', 'blade_bill_ledger', COUNT(*)
|
||||||
|
FROM blade_bill_ledger t
|
||||||
|
INNER JOIN tmp_stat_user u ON u.id = t.create_user
|
||||||
|
WHERE t.create_time >= @stat_start AND t.create_time < @stat_end_exclusive
|
||||||
|
GROUP BY t.create_user
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO tmp_stat_detail (create_user, module_sort, module_name, biz_sort, biz_name, table_name, cnt)
|
||||||
|
SELECT t.create_user, 10, '收付款管理', 7, '汇票付款', 'blade_bill_payment', COUNT(*)
|
||||||
|
FROM blade_bill_payment t
|
||||||
|
INNER JOIN tmp_stat_user u ON u.id = t.create_user
|
||||||
|
WHERE t.create_time >= @stat_start AND t.create_time < @stat_end_exclusive
|
||||||
|
GROUP BY t.create_user
|
||||||
|
;
|
||||||
|
|
||||||
-- 结果 1:账号匹配情况。用户 ID 为空表示库中没有该账号。
|
-- 结果 1:账号匹配情况。用户 ID 为空表示库中没有该账号。
|
||||||
SELECT
|
SELECT
|
||||||
@@ -422,6 +543,8 @@ SELECT
|
|||||||
IFNULL(SUM(CASE WHEN d.module_name = '业务模块' THEN d.cnt ELSE 0 END), 0) AS `业务模块`,
|
IFNULL(SUM(CASE WHEN d.module_name = '业务模块' THEN d.cnt ELSE 0 END), 0) AS `业务模块`,
|
||||||
IFNULL(SUM(CASE WHEN d.module_name = '车/船务模块' THEN d.cnt ELSE 0 END), 0) AS `车/船务模块`,
|
IFNULL(SUM(CASE WHEN d.module_name = '车/船务模块' THEN d.cnt ELSE 0 END), 0) AS `车/船务模块`,
|
||||||
IFNULL(SUM(CASE WHEN d.module_name = '运力模块' THEN d.cnt ELSE 0 END), 0) AS `运力模块`,
|
IFNULL(SUM(CASE WHEN d.module_name = '运力模块' THEN d.cnt ELSE 0 END), 0) AS `运力模块`,
|
||||||
|
IFNULL(SUM(CASE WHEN d.module_name = '结算管理' THEN d.cnt ELSE 0 END), 0) AS `结算管理`,
|
||||||
|
IFNULL(SUM(CASE WHEN d.module_name = '收付款管理' THEN d.cnt ELSE 0 END), 0) AS `收付款管理`,
|
||||||
IFNULL(SUM(d.cnt), 0) AS `合计`
|
IFNULL(SUM(d.cnt), 0) AS `合计`
|
||||||
FROM tmp_stat_account a
|
FROM tmp_stat_account a
|
||||||
LEFT JOIN tmp_stat_user u ON u.account = a.account
|
LEFT JOIN tmp_stat_user u ON u.account = a.account
|
||||||
|
|||||||
Reference in New Issue
Block a user