1、新增预结算单
2、新增正式结算单 3、调整IAM认证登录
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
*/
|
||||
package org.springblade.auth.config;
|
||||
|
||||
import org.springblade.auth.granter.IamAwareTokenGranterFactory;
|
||||
import org.springblade.auth.handler.BladeAuthorizationHandler;
|
||||
import org.springblade.auth.handler.BladeLockHandler;
|
||||
import org.springblade.auth.handler.BladeLogHandler;
|
||||
@@ -37,6 +38,9 @@ import org.springblade.core.jwt.props.JwtProperties;
|
||||
import org.springblade.core.launch.props.BladeProperties;
|
||||
import org.springblade.core.launch.server.ServerInfo;
|
||||
import org.springblade.core.oauth2.config.OAuth2AutoConfiguration;
|
||||
import org.springblade.core.oauth2.granter.TokenGranter;
|
||||
import org.springblade.core.oauth2.granter.TokenGranterEnhancer;
|
||||
import org.springblade.core.oauth2.granter.TokenGranterFactory;
|
||||
import org.springblade.core.oauth2.handler.AuthorizationHandler;
|
||||
import org.springblade.core.oauth2.handler.PasswordHandler;
|
||||
import org.springblade.core.oauth2.handler.TokenHandler;
|
||||
@@ -51,8 +55,11 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* BladeAuthConfiguration
|
||||
*
|
||||
@@ -101,4 +108,12 @@ public class BladeAuthConfiguration {
|
||||
return new BladeUserDetailService(userClient);
|
||||
}
|
||||
|
||||
@Primary
|
||||
@Bean("iamAwareTokenGranterFactory")
|
||||
public TokenGranterFactory tokenGranterFactory(List<TokenGranter> tokenGranters,
|
||||
List<TokenGranterEnhancer> tokenGranterEnhancers,
|
||||
OAuth2Properties properties) {
|
||||
return new IamAwareTokenGranterFactory(tokenGranters, tokenGranterEnhancers, properties);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -65,8 +65,10 @@ import java.net.http.HttpResponse;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.util.Base64;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -167,7 +169,7 @@ public class IamSsoTokenGranter extends AuthorizationCodeGranter {
|
||||
return result.getData();
|
||||
}
|
||||
log.info("IAM统一身份认证未匹配到本系统账号,开始自动创建用户,tenantId={}, accountNo={}", tenantId, accountNo);
|
||||
R<Boolean> saveResult = userClient.saveUser(buildIamUser(profileResponse, tenantId, accountNo));
|
||||
R<Boolean> saveResult = userClient.saveIamUser(buildIamUser(profileResponse, tenantId, accountNo));
|
||||
if (!saveResult.isSuccess() || !Boolean.TRUE.equals(saveResult.getData())) {
|
||||
log.warn("IAM统一身份认证自动创建用户失败,tenantId={}, accountNo={}, msg={}", tenantId, accountNo, saveResult.getMsg());
|
||||
throw new UserInvalidException(OAuth2TokenConstant.USER_NOT_FOUND);
|
||||
@@ -185,12 +187,14 @@ public class IamSsoTokenGranter extends AuthorizationCodeGranter {
|
||||
user.setTenantId(tenantId);
|
||||
user.setUserType(UserType.WEB.getCategory());
|
||||
user.setAccount(accountNo);
|
||||
user.setPassword(accountNo);
|
||||
user.setPassword(UUID.randomUUID().toString());
|
||||
user.setName(accountNo);
|
||||
user.setRealName(accountNo);
|
||||
user.setRoleId(StringPool.MINUS_ONE);
|
||||
user.setDeptId(StringPool.MINUS_ONE);
|
||||
user.setPostId(StringPool.MINUS_ONE);
|
||||
user.setIsOa(1);
|
||||
user.setSyncTime(new Date());
|
||||
user.setStatus(StatusType.ACTIVE.getType());
|
||||
log.info("IAM统一身份认证自动创建用户参数,tenantId={}, accountNo={}, iamId={}", tenantId, accountNo, profileResponse.getId());
|
||||
return user;
|
||||
@@ -206,13 +210,13 @@ public class IamSsoTokenGranter extends AuthorizationCodeGranter {
|
||||
}
|
||||
|
||||
private boolean isIamRequest(OAuth2Request request, boolean logMiss) {
|
||||
String redirectUri = normalizeRedirectUri(request.getRedirectUri());
|
||||
boolean iamRequest = StringUtil.isNotBlank(properties.getRedirectUri())
|
||||
String redirectUri = resolveRedirectUri(request);
|
||||
boolean iamRequest = StringUtil.isNotBlank(redirectUri)
|
||||
&& StringUtil.isNotBlank(request.getCode())
|
||||
&& StringUtil.equals(properties.getRedirectUri(), redirectUri);
|
||||
&& isDedicatedIamEndpoint(request);
|
||||
if (!iamRequest && logMiss) {
|
||||
log.info("IAM统一身份认证请求未命中,configRedirectUri={}, requestRedirectUri={}, normalizedRedirectUri={}, code={}",
|
||||
properties.getRedirectUri(), request.getRedirectUri(), redirectUri, request.getCode());
|
||||
log.info("IAM统一身份认证请求未命中,configRedirectUri={}, requestRedirectUri={}, normalizedRedirectUri={}, hasCode={}",
|
||||
properties.getRedirectUri(), request.getRedirectUri(), redirectUri, StringUtil.isNotBlank(request.getCode()));
|
||||
}
|
||||
return iamRequest;
|
||||
}
|
||||
@@ -247,8 +251,7 @@ public class IamSsoTokenGranter extends AuthorizationCodeGranter {
|
||||
properties.getTokenUrl(),
|
||||
properties.getProfileUrl(),
|
||||
properties.getClientId(),
|
||||
properties.getClientSecret(),
|
||||
properties.getRedirectUri()
|
||||
properties.getClientSecret()
|
||||
)) {
|
||||
throw new UserInvalidException("IAM统一身份认证配置不完整");
|
||||
}
|
||||
@@ -265,7 +268,7 @@ public class IamSsoTokenGranter extends AuthorizationCodeGranter {
|
||||
.header(HttpHeaders.AUTHORIZATION, authorizationHeader())
|
||||
.POST(HttpRequest.BodyPublishers.ofString(tokenBody, StandardCharsets.UTF_8))
|
||||
.build();
|
||||
log.info("IAM统一身份认证换取Token请求,method={}, headers={}, body={}", httpRequest.method(), httpRequest.headers().map(), tokenBody);
|
||||
log.info("IAM统一身份认证换取Token请求,url={}, method={}", properties.getTokenUrl(), httpRequest.method());
|
||||
HttpResponse<String> response = httpClient.send(
|
||||
httpRequest,
|
||||
HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)
|
||||
@@ -292,12 +295,12 @@ public class IamSsoTokenGranter extends AuthorizationCodeGranter {
|
||||
.header(HttpHeaders.AUTHORIZATION, profileAuthorizationHeader(accessToken))
|
||||
.GET()
|
||||
.build();
|
||||
log.info("IAM统一身份认证获取用户信息请求,headers={}, body={}", httpRequest.headers().map(), "无");
|
||||
log.info("IAM统一身份认证获取用户信息请求,url={}, method={}", properties.getProfileUrl(), httpRequest.method());
|
||||
HttpResponse<String> response = httpClient.send(
|
||||
httpRequest,
|
||||
HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)
|
||||
);
|
||||
log.info("IAM统一身份认证获取用户信息响应,headers={}, body={}", response.headers().map(), response.body());
|
||||
log.info("IAM统一身份认证获取用户信息响应,status={}", response.statusCode());
|
||||
if (response.statusCode() < 200 || response.statusCode() >= 300) {
|
||||
log.warn("IAM统一身份认证获取用户信息失败,status={}", response.statusCode());
|
||||
throw new UserInvalidException(OAuth2TokenConstant.TOKEN_NOT_CORRECT);
|
||||
@@ -321,10 +324,24 @@ public class IamSsoTokenGranter extends AuthorizationCodeGranter {
|
||||
if (StringUtil.isNotBlank(request.getState())) {
|
||||
params.put("state", request.getState());
|
||||
}
|
||||
params.put("redirect_uri", properties.getRedirectUri());
|
||||
params.put("redirect_uri", resolveRedirectUri(request));
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 IAM 回调地址,优先使用前端请求传入的值,兼容未传参时的后端默认配置。
|
||||
*
|
||||
* @param request OAuth2 请求
|
||||
* @return IAM 回调地址
|
||||
*/
|
||||
private String resolveRedirectUri(OAuth2Request request) {
|
||||
String requestRedirectUri = normalizeRedirectUri(request.getRedirectUri());
|
||||
if (StringUtil.isNotBlank(requestRedirectUri)) {
|
||||
return requestRedirectUri;
|
||||
}
|
||||
return normalizeRedirectUri(properties.getRedirectUri());
|
||||
}
|
||||
|
||||
private String buildTokenBody(Map<String, String> params) {
|
||||
return params.entrySet().stream()
|
||||
.map(entry -> encode(entry.getKey()) + "=" + encode(entry.getValue()))
|
||||
|
||||
@@ -89,3 +89,16 @@ social:
|
||||
client-id: 233************
|
||||
client-secret: 233************************************
|
||||
redirect-uri: ${social.domain}/oauth/redirect/dingtalk
|
||||
|
||||
# IAM统一身份认证
|
||||
iam:
|
||||
sso:
|
||||
token-url: ${IAM_SSO_TOKEN_URL:http://172.16.204.83:38000/gwzh/IAM/IAM_SSO_TOKEN}
|
||||
profile-url: ${IAM_SSO_PROFILE_URL:http://172.16.204.83:38000/gwzh/IAM/IAM_SSO_PROFILE}
|
||||
client-id: ${IAM_SSO_CLIENT_ID:f0b52f23f71b1649c468}
|
||||
client-secret: ${IAM_SSO_CLIENT_SECRET:5b3d8575f0899946623ab86523ac3dd8ee98}
|
||||
system-client-id: ${IAM_SSO_SYSTEM_CLIENT_ID:saber3}
|
||||
system-client-secret: ${IAM_SSO_SYSTEM_CLIENT_SECRET:saber3_secret}
|
||||
redirect-uri: ${IAM_SSO_REDIRECT_URI:http://172.16.203.228:8000/callback}
|
||||
authorization: ${IAM_SSO_AUTHORIZATION:Z3d6aF90bXMtOVJJU0RVN1U6YW0yYkcwWnBJZ0RQZmtrSjNaZkZjUDBSaGFuSEtxQng=}
|
||||
profile-authorization: ${IAM_SSO_PROFILE_AUTHORIZATION:Z3d6aF90bXMtOVJJU0RVN1U6YW0yYkcwWnBJZ0RQZmtrSjNaZkZjUDBSaGFuSEtxQng=}
|
||||
|
||||
@@ -61,6 +61,7 @@ public class AuthProvider {
|
||||
DEFAULT_SKIP_URL.add("/process/diagram-view");
|
||||
DEFAULT_SKIP_URL.add("/manager/check-upload");
|
||||
DEFAULT_SKIP_URL.add("/assets/**");
|
||||
DEFAULT_SKIP_URL.add("/iam/sso/token/**");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+9
@@ -70,6 +70,7 @@ public interface ISysClient {
|
||||
String PARAM = API_PREFIX + "/param";
|
||||
String PARAM_VALUE = API_PREFIX + "/param-value";
|
||||
String REGION = API_PREFIX + "/region";
|
||||
String FEE_ITEMS = API_PREFIX + "/fee-items";
|
||||
|
||||
/**
|
||||
* 获取菜单
|
||||
@@ -292,4 +293,12 @@ public interface ISysClient {
|
||||
@GetMapping(REGION)
|
||||
R<Region> getRegion(@RequestParam("code") String code);
|
||||
|
||||
/**
|
||||
* 获取启用的费用项
|
||||
*
|
||||
* @return 费用项集合
|
||||
*/
|
||||
@GetMapping(FEE_ITEMS)
|
||||
R<List<FeeItem>> getFeeItems();
|
||||
|
||||
}
|
||||
|
||||
+5
@@ -159,5 +159,10 @@ public class ISysClientFallback implements ISysClient {
|
||||
return R.fail("获取数据失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<List<FeeItem>> getFeeItems() {
|
||||
return R.fail("获取数据失败");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* 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.pojo.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/** 正式结算付款申请请求。 @author Chill */
|
||||
@Data
|
||||
public class FormalSettlementPaymentRequest implements Serializable {
|
||||
@Serial private static final long serialVersionUID = 1L;
|
||||
private Long id;
|
||||
private BigDecimal appliedAmount;
|
||||
private String remark;
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 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.pojo.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/** 正式结算保存请求。 @author Chill */
|
||||
@Data
|
||||
public class FormalSettlementSaveRequest implements Serializable {
|
||||
@Serial private static final long serialVersionUID = 1L;
|
||||
private Long id;
|
||||
private Long contractId;
|
||||
private String settlementType;
|
||||
private List<Long> sourcePreSettlementIds;
|
||||
private List<Long> sourceDetailIds;
|
||||
private LocalDate exchangeRateDate;
|
||||
private BigDecimal exchangeRate;
|
||||
private String attachmentsJson;
|
||||
private String remark;
|
||||
}
|
||||
+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.pojo.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/** 正式结算状态操作请求。 @author Chill */
|
||||
@Data
|
||||
public class FormalSettlementStatusRequest implements Serializable {
|
||||
@Serial private static final long serialVersionUID = 1L;
|
||||
private Long id;
|
||||
private String reason;
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* 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.pojo.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 预结算预付申请请求
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "预结算预付申请请求")
|
||||
public class PreSettlementAdvanceRequest implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "预结算单ID")
|
||||
private Long preSettlementId;
|
||||
|
||||
@Schema(description = "申请预付金额")
|
||||
private BigDecimal appliedAmount;
|
||||
|
||||
@Schema(description = "金蝶预付单号")
|
||||
private String kingdeeAdvanceNo;
|
||||
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* 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.pojo.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 预结算明细调整请求
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "预结算明细调整请求")
|
||||
public class PreSettlementDetailAdjustRequest implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "预结算明细ID")
|
||||
private Long detailId;
|
||||
|
||||
@Schema(description = "调整原因")
|
||||
private String changeReason;
|
||||
|
||||
@Schema(description = "明细费用行")
|
||||
private List<FeeRow> rows;
|
||||
|
||||
@Data
|
||||
@Schema(description = "明细费用行")
|
||||
public static class FeeRow implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "费用快照ID")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "运输总量")
|
||||
private BigDecimal transportQuantity;
|
||||
|
||||
@Schema(description = "里程")
|
||||
private BigDecimal mileage;
|
||||
|
||||
@Schema(description = "运输单价")
|
||||
private BigDecimal unitPrice;
|
||||
|
||||
@Schema(description = "运费")
|
||||
private BigDecimal freightAmount;
|
||||
|
||||
@Schema(description = "费用项目")
|
||||
private Map<String, BigDecimal> feeItems;
|
||||
|
||||
@Schema(description = "结算金额(含税)")
|
||||
private BigDecimal settlementAmountTax;
|
||||
|
||||
@Schema(description = "结算金额(不含税)")
|
||||
private BigDecimal settlementAmountNoTax;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
}
|
||||
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* 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>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.transport.pojo.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 预结算单保存请求
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "预结算单保存请求")
|
||||
public class PreSettlementSaveRequest implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "预结算单ID")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "合同ID")
|
||||
private Long contractId;
|
||||
|
||||
@Schema(description = "汇率日期")
|
||||
private LocalDate exchangeRateDate;
|
||||
|
||||
@Schema(description = "结算汇率")
|
||||
private BigDecimal exchangeRate;
|
||||
|
||||
@Schema(description = "附件JSON")
|
||||
private String attachmentsJson;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "应收应付明细ID")
|
||||
private List<Long> sourceDetailIds;
|
||||
|
||||
@Schema(description = "结算合计费用")
|
||||
private List<SummaryFee> summaryFees;
|
||||
|
||||
@Data
|
||||
@Schema(description = "结算合计费用")
|
||||
public static class SummaryFee implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "合计费用ID")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "费用类型")
|
||||
private String feeType;
|
||||
|
||||
@Schema(description = "费用项")
|
||||
private String feeItem;
|
||||
|
||||
@Schema(description = "调整金额")
|
||||
private BigDecimal adjustAmount;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "是否手工添加")
|
||||
private Integer manualFlag;
|
||||
}
|
||||
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* 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.pojo.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 预结算状态操作请求
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "预结算状态操作请求")
|
||||
public class PreSettlementStatusRequest implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "预结算单ID")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "操作原因")
|
||||
private String reason;
|
||||
|
||||
@Schema(description = "当前节点")
|
||||
private String currentNode;
|
||||
|
||||
@Schema(description = "当前处理人")
|
||||
private String currentProcessor;
|
||||
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* 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.pojo.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.core.tenant.mp.TenantEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 正式结算单实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("blade_formal_settlement")
|
||||
@Schema(description = "正式结算单")
|
||||
public class FormalSettlement extends TenantEntity {
|
||||
@Serial private static final long serialVersionUID = 1L;
|
||||
private String formalSettlementNo;
|
||||
private String sourceType;
|
||||
private String settlementType;
|
||||
private Long projectId;
|
||||
private String projectName;
|
||||
private Long deptId;
|
||||
private String deptName;
|
||||
private Long contractId;
|
||||
private String contractNo;
|
||||
private String contractName;
|
||||
private String payerName;
|
||||
private String payeeName;
|
||||
private String currency;
|
||||
private BigDecimal settlementAmount;
|
||||
private String localCurrency;
|
||||
private BigDecimal localSettlementAmount;
|
||||
private BigDecimal appliedPaymentAmount;
|
||||
private BigDecimal paidAmount;
|
||||
private LocalDate exchangeRateDate;
|
||||
private BigDecimal exchangeRate;
|
||||
private String invoiceStatus;
|
||||
private String paymentStatus;
|
||||
private String approvalStatus;
|
||||
private String currentNode;
|
||||
private String currentProcessor;
|
||||
private String kingdeeBillNo;
|
||||
private String kingdeeSyncStatus;
|
||||
private String attachmentsJson;
|
||||
private String remark;
|
||||
private LocalDateTime approvedTime;
|
||||
private LocalDateTime syncedTime;
|
||||
private String voidReason;
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* 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.pojo.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.core.tenant.mp.TenantEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 正式结算明细快照实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("blade_formal_settlement_detail")
|
||||
public class FormalSettlementDetail extends TenantEntity {
|
||||
@Serial private static final long serialVersionUID = 1L;
|
||||
private Long formalSettlementId;
|
||||
private Long sourcePreSettlementId;
|
||||
private Long sourcePreSettlementDetailId;
|
||||
private Long sourceDetailId;
|
||||
private Integer lineNo;
|
||||
private String documentNo;
|
||||
private Long waybillId;
|
||||
private String waybillNo;
|
||||
private String vehicleNo;
|
||||
private String departureAddress;
|
||||
private String arrivalAddress;
|
||||
private LocalDateTime actualDepartureTime;
|
||||
private LocalDateTime actualCompletionTime;
|
||||
private String transportType;
|
||||
private String cargoName;
|
||||
private String cargoType;
|
||||
private BigDecimal transportQuantity;
|
||||
private String quantityUnit;
|
||||
private BigDecimal mileage;
|
||||
private String batchNo;
|
||||
private BigDecimal unitPrice;
|
||||
private BigDecimal freightAmount;
|
||||
private String feeItemsJson;
|
||||
private BigDecimal originalAmount;
|
||||
private BigDecimal adjustAmount;
|
||||
private BigDecimal settlementAmountTax;
|
||||
private BigDecimal settlementAmountNoTax;
|
||||
private String currency;
|
||||
private String remark;
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* 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.pojo.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.core.tenant.mp.TenantEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 正式结算货物费用快照实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("blade_formal_settlement_detail_fee")
|
||||
public class FormalSettlementDetailFee extends TenantEntity {
|
||||
@Serial private static final long serialVersionUID = 1L;
|
||||
private Long formalSettlementDetailId;
|
||||
private Long sourceFeeId;
|
||||
private String lineNo;
|
||||
private String cargoName;
|
||||
private String cargoType;
|
||||
private BigDecimal transportQuantity;
|
||||
private String quantityUnit;
|
||||
private BigDecimal mileage;
|
||||
private BigDecimal unitPrice;
|
||||
private BigDecimal freightAmount;
|
||||
private String feeItemsJson;
|
||||
private BigDecimal originalAmount;
|
||||
private BigDecimal adjustAmount;
|
||||
private BigDecimal settlementAmountTax;
|
||||
private BigDecimal settlementAmountNoTax;
|
||||
private String remark;
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* 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.pojo.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.core.tenant.mp.TenantEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 正式结算付款申请实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("blade_formal_settlement_payment")
|
||||
public class FormalSettlementPayment extends TenantEntity {
|
||||
@Serial private static final long serialVersionUID = 1L;
|
||||
private Long formalSettlementId;
|
||||
private String paymentNo;
|
||||
private String paymentType;
|
||||
private BigDecimal appliedAmount;
|
||||
private BigDecimal paidAmount;
|
||||
private String billStatus;
|
||||
private String kingdeeBillNo;
|
||||
private String remark;
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* 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.pojo.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.core.tenant.mp.TenantEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 正式结算来源预结算实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("blade_formal_settlement_source")
|
||||
public class FormalSettlementSource extends TenantEntity {
|
||||
@Serial private static final long serialVersionUID = 1L;
|
||||
private Long formalSettlementId;
|
||||
private Long preSettlementId;
|
||||
private String preSettlementNo;
|
||||
private BigDecimal settlementAmount;
|
||||
private BigDecimal advanceAppliedAmount;
|
||||
private BigDecimal advancePaidAmount;
|
||||
}
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* 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>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.transport.pojo.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.core.tenant.mp.TenantEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 预结算单实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("blade_pre_settlement")
|
||||
@Schema(description = "预结算单")
|
||||
public class PreSettlement extends TenantEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "预结算单号")
|
||||
private String preSettlementNo;
|
||||
|
||||
@Schema(description = "来源")
|
||||
private String sourceType;
|
||||
|
||||
@Schema(description = "结算类型:receivable/payable")
|
||||
private String settlementType;
|
||||
|
||||
@Schema(description = "项目ID")
|
||||
private Long projectId;
|
||||
|
||||
@Schema(description = "项目名称")
|
||||
private String projectName;
|
||||
|
||||
@Schema(description = "所属组织ID")
|
||||
private Long deptId;
|
||||
|
||||
@Schema(description = "所属组织")
|
||||
private String deptName;
|
||||
|
||||
@Schema(description = "合同ID")
|
||||
private Long contractId;
|
||||
|
||||
@Schema(description = "合同编号")
|
||||
private String contractNo;
|
||||
|
||||
@Schema(description = "合同名称")
|
||||
private String contractName;
|
||||
|
||||
@Schema(description = "付款方")
|
||||
private String payerName;
|
||||
|
||||
@Schema(description = "收款方")
|
||||
private String payeeName;
|
||||
|
||||
@Schema(description = "结算币种")
|
||||
private String currency;
|
||||
|
||||
@Schema(description = "结算金额")
|
||||
private BigDecimal settlementAmount;
|
||||
|
||||
@Schema(description = "本位币")
|
||||
private String localCurrency;
|
||||
|
||||
@Schema(description = "本位币合计")
|
||||
private BigDecimal localSettlementAmount;
|
||||
|
||||
@Schema(description = "汇率日期")
|
||||
private LocalDate exchangeRateDate;
|
||||
|
||||
@Schema(description = "结算汇率")
|
||||
private BigDecimal exchangeRate;
|
||||
|
||||
@Schema(description = "审核状态:draft/reviewing/approved/returned/voided")
|
||||
private String approvalStatus;
|
||||
|
||||
@Schema(description = "当前节点")
|
||||
private String currentNode;
|
||||
|
||||
@Schema(description = "当前处理人")
|
||||
private String currentProcessor;
|
||||
|
||||
@Schema(description = "预付单号")
|
||||
private String advanceNo;
|
||||
|
||||
@Schema(description = "申请预付金额")
|
||||
private BigDecimal advanceAppliedAmount;
|
||||
|
||||
@Schema(description = "已付款金额")
|
||||
private BigDecimal advancePaidAmount;
|
||||
|
||||
@Schema(description = "正式结算单号")
|
||||
private String formalSettlementNo;
|
||||
|
||||
@Schema(description = "附件JSON")
|
||||
private String attachmentsJson;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "审核通过时间")
|
||||
private LocalDateTime approvedTime;
|
||||
|
||||
@Schema(description = "正式结算时间")
|
||||
private LocalDateTime formalSettledTime;
|
||||
|
||||
@Schema(description = "作废原因")
|
||||
private String voidReason;
|
||||
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* 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.pojo.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.core.tenant.mp.TenantEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 预结算预付记录实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("blade_pre_settlement_advance")
|
||||
@Schema(description = "预结算预付记录")
|
||||
public class PreSettlementAdvance extends TenantEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "预结算单ID")
|
||||
private Long preSettlementId;
|
||||
|
||||
@Schema(description = "预付单号")
|
||||
private String advanceNo;
|
||||
|
||||
@Schema(description = "申请预付金额")
|
||||
private BigDecimal appliedAmount;
|
||||
|
||||
@Schema(description = "已付款金额")
|
||||
private BigDecimal paidAmount;
|
||||
|
||||
@Schema(description = "单据状态:reviewing/approved/paid/returned/voided")
|
||||
private String billStatus;
|
||||
|
||||
@Schema(description = "金蝶预付单号")
|
||||
private String kingdeeAdvanceNo;
|
||||
|
||||
@TableField(exist = false)
|
||||
@Schema(description = "创建人姓名")
|
||||
private String createUserName;
|
||||
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* 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.pojo.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.core.tenant.mp.TenantEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 预结算变更记录实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("blade_pre_settlement_change_record")
|
||||
@Schema(description = "预结算变更记录")
|
||||
public class PreSettlementChangeRecord extends TenantEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "预结算单ID")
|
||||
private Long preSettlementId;
|
||||
|
||||
@Schema(description = "变更类型")
|
||||
private String changeType;
|
||||
|
||||
@Schema(description = "行号")
|
||||
private Integer lineNo;
|
||||
|
||||
@Schema(description = "操作类型")
|
||||
private String operationType;
|
||||
|
||||
@Schema(description = "变更内容")
|
||||
private String changeContent;
|
||||
|
||||
@Schema(description = "操作人")
|
||||
private String operatorName;
|
||||
|
||||
@Schema(description = "变更原因")
|
||||
private String changeReason;
|
||||
|
||||
@Schema(description = "变更时间")
|
||||
private LocalDateTime changeTime;
|
||||
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* 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.pojo.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.core.tenant.mp.TenantEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 预结算明细实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("blade_pre_settlement_detail")
|
||||
@Schema(description = "预结算明细")
|
||||
public class PreSettlementDetail extends TenantEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "预结算单ID")
|
||||
private Long preSettlementId;
|
||||
|
||||
@Schema(description = "应收应付明细ID")
|
||||
private Long sourceDetailId;
|
||||
|
||||
@Schema(description = "行号")
|
||||
private Integer lineNo;
|
||||
|
||||
@Schema(description = "单据号")
|
||||
private String documentNo;
|
||||
|
||||
@Schema(description = "运单ID")
|
||||
private Long waybillId;
|
||||
|
||||
@Schema(description = "运单号")
|
||||
private String waybillNo;
|
||||
|
||||
@Schema(description = "车号")
|
||||
private String vehicleNo;
|
||||
|
||||
@Schema(description = "发货地址")
|
||||
private String departureAddress;
|
||||
|
||||
@Schema(description = "到货地址")
|
||||
private String arrivalAddress;
|
||||
|
||||
@Schema(description = "实际发货时间")
|
||||
private LocalDateTime actualDepartureTime;
|
||||
|
||||
@Schema(description = "实际完成时间")
|
||||
private LocalDateTime actualCompletionTime;
|
||||
|
||||
@Schema(description = "运输类型")
|
||||
private String transportType;
|
||||
|
||||
@Schema(description = "货物名称")
|
||||
private String cargoName;
|
||||
|
||||
@Schema(description = "货物类型")
|
||||
private String cargoType;
|
||||
|
||||
@Schema(description = "运输总量")
|
||||
private BigDecimal transportQuantity;
|
||||
|
||||
@Schema(description = "数量单位")
|
||||
private String quantityUnit;
|
||||
|
||||
@Schema(description = "里程")
|
||||
private BigDecimal mileage;
|
||||
|
||||
@Schema(description = "批次号")
|
||||
private String batchNo;
|
||||
|
||||
@Schema(description = "运输单价")
|
||||
private BigDecimal unitPrice;
|
||||
|
||||
@Schema(description = "运费")
|
||||
private BigDecimal freightAmount;
|
||||
|
||||
@Schema(description = "费用项JSON")
|
||||
private String feeItemsJson;
|
||||
|
||||
@Schema(description = "原金额")
|
||||
private BigDecimal originalAmount;
|
||||
|
||||
@Schema(description = "调整金额")
|
||||
private BigDecimal adjustAmount;
|
||||
|
||||
@Schema(description = "结算金额(含税)")
|
||||
private BigDecimal settlementAmountTax;
|
||||
|
||||
@Schema(description = "结算金额(不含税)")
|
||||
private BigDecimal settlementAmountNoTax;
|
||||
|
||||
@Schema(description = "币种")
|
||||
private String currency;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* 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.pojo.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.core.tenant.mp.TenantEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 预结算明细费用快照实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("blade_pre_settlement_detail_fee")
|
||||
@Schema(description = "预结算明细费用快照")
|
||||
public class PreSettlementDetailFee extends TenantEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "预结算明细ID")
|
||||
private Long preSettlementDetailId;
|
||||
|
||||
@Schema(description = "源费用行ID")
|
||||
private Long sourceFeeId;
|
||||
|
||||
@Schema(description = "行号")
|
||||
private String lineNo;
|
||||
|
||||
@Schema(description = "货物名称")
|
||||
private String cargoName;
|
||||
|
||||
@Schema(description = "货物类型")
|
||||
private String cargoType;
|
||||
|
||||
@Schema(description = "运输量")
|
||||
private BigDecimal transportQuantity;
|
||||
|
||||
@Schema(description = "数量单位")
|
||||
private String quantityUnit;
|
||||
|
||||
@Schema(description = "里程")
|
||||
private BigDecimal mileage;
|
||||
|
||||
@Schema(description = "运输单价")
|
||||
private BigDecimal unitPrice;
|
||||
|
||||
@Schema(description = "运费")
|
||||
private BigDecimal freightAmount;
|
||||
|
||||
@Schema(description = "费用项JSON")
|
||||
private String feeItemsJson;
|
||||
|
||||
@Schema(description = "原金额")
|
||||
private BigDecimal originalAmount;
|
||||
|
||||
@Schema(description = "调整金额")
|
||||
private BigDecimal adjustAmount;
|
||||
|
||||
@Schema(description = "结算金额(含税)")
|
||||
private BigDecimal settlementAmountTax;
|
||||
|
||||
@Schema(description = "结算金额(不含税)")
|
||||
private BigDecimal settlementAmountNoTax;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* 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.pojo.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.core.tenant.mp.TenantEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 预结算合计费用实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("blade_pre_settlement_summary_fee")
|
||||
@Schema(description = "预结算合计费用")
|
||||
public class PreSettlementSummaryFee extends TenantEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "预结算单ID")
|
||||
private Long preSettlementId;
|
||||
|
||||
@Schema(description = "行号")
|
||||
private Integer lineNo;
|
||||
|
||||
@Schema(description = "费用类型")
|
||||
private String feeType;
|
||||
|
||||
@Schema(description = "费用项")
|
||||
private String feeItem;
|
||||
|
||||
@Schema(description = "原金额")
|
||||
private BigDecimal originalAmount;
|
||||
|
||||
@Schema(description = "调整金额")
|
||||
private BigDecimal adjustAmount;
|
||||
|
||||
@Schema(description = "结算金额")
|
||||
private BigDecimal settlementAmount;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "是否手工添加")
|
||||
private Integer manualFlag;
|
||||
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* 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.pojo.vo;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlement;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlementDetail;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlementSource;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlementPayment;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 正式结算单视图实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class FormalSettlementVO extends FormalSettlement {
|
||||
@Serial private static final long serialVersionUID = 1L;
|
||||
@TableField(exist = false) @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate createStartDate;
|
||||
@TableField(exist = false) @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate createEndDate;
|
||||
@TableField(exist = false) private String createUserName;
|
||||
@TableField(exist = false) private String approvalStatusName;
|
||||
@TableField(exist = false) private String settlementTypeName;
|
||||
@TableField(exist = false) private String preSettlementNos;
|
||||
@TableField(exist = false) private String preSettlementNo;
|
||||
@TableField(exist = false) private List<FormalSettlementSource> sources;
|
||||
@TableField(exist = false) private List<FormalSettlementDetail> details;
|
||||
@TableField(exist = false) private List<FormalSettlementPayment> payments;
|
||||
}
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* 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>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.transport.pojo.vo;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.transport.pojo.entity.PreSettlement;
|
||||
import org.springblade.transport.pojo.entity.PreSettlementAdvance;
|
||||
import org.springblade.transport.pojo.entity.PreSettlementChangeRecord;
|
||||
import org.springblade.transport.pojo.entity.PreSettlementDetail;
|
||||
import org.springblade.transport.pojo.entity.PreSettlementDetailFee;
|
||||
import org.springblade.transport.pojo.entity.PreSettlementSummaryFee;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 预结算单视图实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Schema(description = "预结算单")
|
||||
public class PreSettlementVO extends PreSettlement {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableField(exist = false)
|
||||
@Schema(description = "生成开始日期")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
private LocalDate createStartDate;
|
||||
|
||||
@TableField(exist = false)
|
||||
@Schema(description = "生成结束日期")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
private LocalDate createEndDate;
|
||||
|
||||
@TableField(exist = false)
|
||||
@Schema(description = "创建人姓名")
|
||||
private String createUserName;
|
||||
|
||||
@TableField(exist = false)
|
||||
@Schema(description = "更新人姓名")
|
||||
private String updateUserName;
|
||||
|
||||
@TableField(exist = false)
|
||||
@Schema(description = "审核状态名称")
|
||||
private String approvalStatusName;
|
||||
|
||||
@TableField(exist = false)
|
||||
@Schema(description = "结算类型名称")
|
||||
private String settlementTypeName;
|
||||
|
||||
@TableField(exist = false)
|
||||
@Schema(description = "结算明细")
|
||||
private List<PreSettlementDetail> details;
|
||||
|
||||
@TableField(exist = false)
|
||||
@Schema(description = "明细费用快照")
|
||||
private Map<Long, List<PreSettlementDetailFee>> detailFees;
|
||||
|
||||
@TableField(exist = false)
|
||||
@Schema(description = "结算合计")
|
||||
private List<PreSettlementSummaryFee> summaryFees;
|
||||
|
||||
@TableField(exist = false)
|
||||
@Schema(description = "预付信息")
|
||||
private List<PreSettlementAdvance> advances;
|
||||
|
||||
@TableField(exist = false)
|
||||
@Schema(description = "变更记录")
|
||||
private List<PreSettlementChangeRecord> changeRecords;
|
||||
|
||||
@TableField(exist = false)
|
||||
@Schema(description = "打印模板")
|
||||
private List<Map<String, String>> printTemplates;
|
||||
|
||||
}
|
||||
+10
@@ -57,6 +57,7 @@ public interface IUserClient {
|
||||
String USER_BY_ACCOUNT = API_PREFIX + "/user-by-account";
|
||||
String USER_AUTH_INFO = API_PREFIX + "/user-auth-info";
|
||||
String SAVE_USER = API_PREFIX + "/save-user";
|
||||
String SAVE_IAM_USER = API_PREFIX + "/save-iam-user";
|
||||
String REGISTER_USER = API_PREFIX + "/register-user";
|
||||
String REMOVE_USER = API_PREFIX + "/remove-user";
|
||||
|
||||
@@ -149,6 +150,15 @@ public interface IUserClient {
|
||||
@PostMapping(SAVE_USER)
|
||||
R<Boolean> saveUser(@RequestBody User user);
|
||||
|
||||
/**
|
||||
* 新建IAM用户
|
||||
*
|
||||
* @param user 用户实体
|
||||
* @return 是否成功
|
||||
*/
|
||||
@PostMapping(SAVE_IAM_USER)
|
||||
R<Boolean> saveIamUser(@RequestBody User user);
|
||||
|
||||
/**
|
||||
* 注册用户
|
||||
*
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
*/
|
||||
package org.springblade.system.feign;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.core.tenant.annotation.NonDS;
|
||||
import org.springblade.core.tool.api.R;
|
||||
@@ -63,6 +64,8 @@ public class SysClient implements ISysClient {
|
||||
|
||||
private final IRegionService regionService;
|
||||
|
||||
private final IFeeItemService feeItemService;
|
||||
|
||||
@Override
|
||||
@GetMapping(MENU)
|
||||
public R<Menu> getMenu(Long id) {
|
||||
@@ -200,5 +203,14 @@ public class SysClient implements ISysClient {
|
||||
return R.data(regionService.getById(code));
|
||||
}
|
||||
|
||||
@Override
|
||||
@GetMapping(FEE_ITEMS)
|
||||
public R<List<FeeItem>> getFeeItems() {
|
||||
return R.data(feeItemService.list(Wrappers.<FeeItem>lambdaQuery()
|
||||
.eq(FeeItem::getStatus, 1)
|
||||
.eq(FeeItem::getIsDeleted, 0)
|
||||
.orderByAsc(FeeItem::getFeeCategory, FeeItem::getName)));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -108,6 +108,12 @@ public class UserClient implements IUserClient {
|
||||
return R.data(service.submit(user));
|
||||
}
|
||||
|
||||
@Override
|
||||
@PostMapping(SAVE_IAM_USER)
|
||||
public R<Boolean> saveIamUser(@RequestBody User user) {
|
||||
return R.data(service.saveIamUser(user));
|
||||
}
|
||||
|
||||
@Override
|
||||
@PostMapping(REGISTER_USER)
|
||||
public R<String> registerUser(User user) {
|
||||
|
||||
+8
@@ -280,6 +280,14 @@ public interface IUserService extends BaseService<User> {
|
||||
*/
|
||||
boolean registerUser(User user);
|
||||
|
||||
/**
|
||||
* 新建IAM统一身份认证用户(按可信租户落库)
|
||||
*
|
||||
* @param user 用户实体
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean saveIamUser(User user);
|
||||
|
||||
/**
|
||||
* 配置用户平台扩展信息(租户守卫校验用户归属)
|
||||
*
|
||||
|
||||
+30
@@ -74,6 +74,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -549,6 +550,35 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
|
||||
return saveUser(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean saveIamUser(User user) {
|
||||
if (AuthUtil.hasAuth()) {
|
||||
throw new ServiceException("IAM用户创建仅允许统一身份认证流程调用!");
|
||||
}
|
||||
Tenant tenant = SysCache.getTenant(user.getTenantId());
|
||||
if (tenant == null || tenant.getId() == null) {
|
||||
throw new ServiceException("租户信息错误!");
|
||||
}
|
||||
if (user.getUserType() == null) {
|
||||
user.setUserType(UserType.WEB.getCategory());
|
||||
}
|
||||
if (StringUtil.isBlank(user.getRoleId())) {
|
||||
user.setRoleId(StringPool.MINUS_ONE);
|
||||
}
|
||||
if (StringUtil.isBlank(user.getDeptId())) {
|
||||
user.setDeptId(StringPool.MINUS_ONE);
|
||||
}
|
||||
if (StringUtil.isBlank(user.getPostId())) {
|
||||
user.setPostId(StringPool.MINUS_ONE);
|
||||
}
|
||||
user.setIsOa(1);
|
||||
user.setSyncTime(new Date());
|
||||
user.setStatus(StatusType.ACTIVE.getType());
|
||||
applyUserDefaults(user);
|
||||
return saveUser(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean updatePlatform(Long userId, Integer userType, String userExt) {
|
||||
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
/**
|
||||
* 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.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.core.boot.ctrl.BladeController;
|
||||
import org.springblade.core.mp.support.Condition;
|
||||
import org.springblade.core.mp.support.Query;
|
||||
import org.springblade.core.secure.annotation.PreAuth;
|
||||
import org.springblade.core.tool.api.R;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementSaveRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementPaymentRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementStatusRequest;
|
||||
import org.springblade.transport.pojo.dto.PreSettlementDetailAdjustRequest;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlementDetailFee;
|
||||
import org.springblade.transport.pojo.vo.FormalSettlementVO;
|
||||
import org.springblade.transport.pojo.vo.PreSettlementVO;
|
||||
import org.springblade.transport.service.IFormalSettlementService;
|
||||
import org.springblade.transport.service.IPreSettlementService;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 正式结算单控制器
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
@PreAuth(menu = "formal_settlement")
|
||||
@RequestMapping("/formal-settlement")
|
||||
@Tag(name = "正式结算单", description = "正式结算单管理")
|
||||
public class FormalSettlementController extends BladeController {
|
||||
private final IFormalSettlementService formalSettlementService;
|
||||
private final IPreSettlementService preSettlementService;
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperationSupport(order = 1)
|
||||
@Operation(summary = "正式结算单分页")
|
||||
public R<IPage<FormalSettlementVO>> list(FormalSettlementVO query, Query pageQuery) {
|
||||
return R.data(formalSettlementService.selectPage(Condition.getPage(pageQuery), query));
|
||||
}
|
||||
|
||||
@GetMapping("/detail")
|
||||
@ApiOperationSupport(order = 2)
|
||||
@Operation(summary = "正式结算单详情")
|
||||
public R<FormalSettlementVO> detail(@RequestParam Long id) { return R.data(formalSettlementService.detail(id)); }
|
||||
|
||||
@GetMapping("/candidate-pre-settlements")
|
||||
@ApiOperationSupport(order = 3)
|
||||
@Operation(summary = "可合并的预结算单")
|
||||
public R<IPage<PreSettlementVO>> candidates(PreSettlementVO query, Query pageQuery) {
|
||||
return R.data(formalSettlementService.candidatePreSettlements(Condition.getPage(pageQuery), query));
|
||||
}
|
||||
|
||||
@GetMapping("/contract-options")
|
||||
@ApiOperationSupport(order = 4)
|
||||
@Operation(summary = "可选合同")
|
||||
public R<List<Map<String, Object>>> contractOptions(@RequestParam(required = false) String keyword) {
|
||||
return R.data(preSettlementService.contractOptions(keyword));
|
||||
}
|
||||
|
||||
@GetMapping("/candidate-details")
|
||||
@ApiOperationSupport(order = 5)
|
||||
@Operation(summary = "可选应收应付明细")
|
||||
public R<IPage<Map<String, Object>>> candidateDetails(Query query, @RequestParam Long contractId,
|
||||
@RequestParam String settlementType, @RequestParam(required = false) String batchNo,
|
||||
@RequestParam(required = false) String feeStartDate, @RequestParam(required = false) String feeEndDate) {
|
||||
return R.data(preSettlementService.candidateDetails(Condition.getPage(query), contractId,
|
||||
settlementType, batchNo, feeStartDate, feeEndDate));
|
||||
}
|
||||
|
||||
@PostMapping("/save")
|
||||
@ApiOperationSupport(order = 6)
|
||||
@Operation(summary = "保存正式结算草稿")
|
||||
public R<Long> save(@RequestBody FormalSettlementSaveRequest request) { return R.data(formalSettlementService.saveDraft(request)); }
|
||||
|
||||
@PostMapping("/remove")
|
||||
@ApiOperationSupport(order = 7)
|
||||
@Operation(summary = "删除正式结算草稿")
|
||||
public R remove(@RequestParam Long id) { formalSettlementService.removeDraft(id); return R.success("删除成功"); }
|
||||
|
||||
@PostMapping("/submit")
|
||||
@ApiOperationSupport(order = 8)
|
||||
@Operation(summary = "提交审批")
|
||||
public R submit(@RequestBody FormalSettlementStatusRequest request) { formalSettlementService.submit(request); return R.success("提交成功"); }
|
||||
|
||||
@PostMapping("/approve")
|
||||
@ApiOperationSupport(order = 9)
|
||||
@Operation(summary = "审批通过")
|
||||
public R approve(@RequestBody FormalSettlementStatusRequest request) { formalSettlementService.approve(request); return R.success("审批通过"); }
|
||||
|
||||
@PostMapping("/return")
|
||||
@ApiOperationSupport(order = 10)
|
||||
@Operation(summary = "审批驳回")
|
||||
public R returnBill(@RequestBody FormalSettlementStatusRequest request) { formalSettlementService.returnBill(request); return R.success("已驳回"); }
|
||||
|
||||
@PostMapping("/void")
|
||||
@ApiOperationSupport(order = 11)
|
||||
@Operation(summary = "作废正式结算单")
|
||||
public R voidBill(@RequestBody FormalSettlementStatusRequest request) { formalSettlementService.voidBill(request); return R.success("作废成功"); }
|
||||
|
||||
@PostMapping("/sync-kingdee")
|
||||
@ApiOperationSupport(order = 12)
|
||||
@Operation(summary = "推送金蝶应付单")
|
||||
public R<String> syncKingdee(@RequestParam Long id) { return R.data(formalSettlementService.syncKingdee(id)); }
|
||||
|
||||
@GetMapping("/detail-fees")
|
||||
@ApiOperationSupport(order = 13)
|
||||
@Operation(summary = "正式结算货物费用快照")
|
||||
public R<List<FormalSettlementDetailFee>> detailFees(@RequestParam Long detailId) {
|
||||
return R.data(formalSettlementService.detailFees(detailId));
|
||||
}
|
||||
|
||||
@PostMapping("/adjust-detail")
|
||||
@ApiOperationSupport(order = 14)
|
||||
@Operation(summary = "调整草稿结算明细")
|
||||
public R adjustDetail(@RequestBody PreSettlementDetailAdjustRequest request) {
|
||||
formalSettlementService.adjustDetail(request);
|
||||
return R.success("保存成功");
|
||||
}
|
||||
|
||||
@PostMapping("/apply-payment")
|
||||
@ApiOperationSupport(order = 15)
|
||||
@Operation(summary = "发起尾款付款申请")
|
||||
public R<String> applyPayment(@RequestBody FormalSettlementPaymentRequest request) {
|
||||
return R.data(formalSettlementService.applyPayment(request));
|
||||
}
|
||||
}
|
||||
+262
@@ -0,0 +1,262 @@
|
||||
/**
|
||||
* 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>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.transport.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.core.boot.ctrl.BladeController;
|
||||
import org.springblade.core.excel.util.ExcelUtil;
|
||||
import org.springblade.core.mp.support.Condition;
|
||||
import org.springblade.core.mp.support.Query;
|
||||
import org.springblade.core.secure.annotation.PreAuth;
|
||||
import org.springblade.core.tool.api.R;
|
||||
import org.springblade.core.tool.utils.DateUtil;
|
||||
import org.springblade.transport.excel.PreSettlementExcel;
|
||||
import org.springblade.transport.pojo.dto.PreSettlementAdvanceRequest;
|
||||
import org.springblade.transport.pojo.dto.PreSettlementDetailAdjustRequest;
|
||||
import org.springblade.transport.pojo.dto.PreSettlementSaveRequest;
|
||||
import org.springblade.transport.pojo.dto.PreSettlementStatusRequest;
|
||||
import org.springblade.transport.pojo.entity.PreSettlementDetailFee;
|
||||
import org.springblade.transport.pojo.vo.PreSettlementVO;
|
||||
import org.springblade.transport.service.IPreSettlementService;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 预结算单控制器
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
@PreAuth(menu = "pre_settlement")
|
||||
@RequestMapping("/pre-settlement")
|
||||
@Tag(name = "预结算单", description = "预结算单管理")
|
||||
public class PreSettlementController extends BladeController {
|
||||
|
||||
private final IPreSettlementService preSettlementService;
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperationSupport(order = 1)
|
||||
@Operation(summary = "预结算单分页")
|
||||
public R<IPage<PreSettlementVO>> list(PreSettlementVO query, Query pageQuery) {
|
||||
return R.data(preSettlementService.selectPage(Condition.getPage(pageQuery), query));
|
||||
}
|
||||
|
||||
@GetMapping("/detail")
|
||||
@ApiOperationSupport(order = 2)
|
||||
@Operation(summary = "预结算单详情")
|
||||
public R<PreSettlementVO> detail(@RequestParam Long id) {
|
||||
return R.data(preSettlementService.detail(id));
|
||||
}
|
||||
|
||||
@GetMapping("/contract-options")
|
||||
@ApiOperationSupport(order = 3)
|
||||
@Operation(summary = "可选合同")
|
||||
public R<List<Map<String, Object>>> contractOptions(@RequestParam(required = false) String keyword) {
|
||||
return R.data(preSettlementService.contractOptions(keyword));
|
||||
}
|
||||
|
||||
@GetMapping("/fee-options")
|
||||
@ApiOperationSupport(order = 4)
|
||||
@Operation(summary = "费用类型及费用项")
|
||||
public R<List<Map<String, Object>>> feeOptions() {
|
||||
return R.data(preSettlementService.feeOptions());
|
||||
}
|
||||
|
||||
@GetMapping("/candidate-details")
|
||||
@ApiOperationSupport(order = 5)
|
||||
@Operation(summary = "可选应收应付明细")
|
||||
public R<IPage<Map<String, Object>>> candidateDetails(Query query, @RequestParam Long contractId,
|
||||
@RequestParam String settlementType, @RequestParam(required = false) String batchNo,
|
||||
@RequestParam(required = false) String feeStartDate,
|
||||
@RequestParam(required = false) String feeEndDate) {
|
||||
return R.data(preSettlementService.candidateDetails(Condition.getPage(query), contractId,
|
||||
settlementType, batchNo, feeStartDate, feeEndDate));
|
||||
}
|
||||
|
||||
@PostMapping("/save")
|
||||
@ApiOperationSupport(order = 5)
|
||||
@Operation(summary = "保存预结算草稿")
|
||||
public R<Long> save(@RequestBody PreSettlementSaveRequest request) {
|
||||
return R.data(preSettlementService.saveDraft(request));
|
||||
}
|
||||
|
||||
@PostMapping("/remove")
|
||||
@ApiOperationSupport(order = 6)
|
||||
@Operation(summary = "删除预结算草稿")
|
||||
public R remove(@RequestParam Long id) {
|
||||
preSettlementService.removeDraft(id);
|
||||
return R.success("删除成功");
|
||||
}
|
||||
|
||||
@PostMapping("/remove-detail")
|
||||
@ApiOperationSupport(order = 7)
|
||||
@Operation(summary = "移除预结算明细")
|
||||
public R removeDetail(@RequestParam Long id, @RequestParam Long detailId) {
|
||||
preSettlementService.removeDetail(id, detailId);
|
||||
return R.success("移除成功");
|
||||
}
|
||||
|
||||
@PostMapping("/submit")
|
||||
@ApiOperationSupport(order = 8)
|
||||
@Operation(summary = "提交预结算审批")
|
||||
public R submit(@RequestBody PreSettlementStatusRequest request) {
|
||||
preSettlementService.submit(request);
|
||||
return R.success("审批流程已发起");
|
||||
}
|
||||
|
||||
@PostMapping("/approve")
|
||||
@ApiOperationSupport(order = 9)
|
||||
@Operation(summary = "预结算审批通过")
|
||||
public R approve(@RequestBody PreSettlementStatusRequest request) {
|
||||
preSettlementService.approve(request);
|
||||
return R.success("审批通过");
|
||||
}
|
||||
|
||||
@PostMapping("/return")
|
||||
@ApiOperationSupport(order = 10)
|
||||
@Operation(summary = "预结算审批驳回")
|
||||
public R returnBill(@RequestBody PreSettlementStatusRequest request) {
|
||||
preSettlementService.returnBill(request);
|
||||
return R.success("已驳回");
|
||||
}
|
||||
|
||||
@PostMapping("/void")
|
||||
@ApiOperationSupport(order = 11)
|
||||
@Operation(summary = "作废预结算单")
|
||||
public R voidBill(@RequestBody PreSettlementStatusRequest request) {
|
||||
preSettlementService.voidBill(request);
|
||||
return R.success("作废成功");
|
||||
}
|
||||
|
||||
@PostMapping("/apply-advance")
|
||||
@ApiOperationSupport(order = 12)
|
||||
@Operation(summary = "发起预付申请")
|
||||
public R applyAdvance(@RequestBody PreSettlementAdvanceRequest request) {
|
||||
preSettlementService.applyAdvance(request);
|
||||
return R.success("预付申请提交成功");
|
||||
}
|
||||
|
||||
@PostMapping("/update-advance-paid")
|
||||
@ApiOperationSupport(order = 13)
|
||||
@Operation(summary = "回写预付付款金额")
|
||||
public R updateAdvancePaid(@RequestParam Long advanceId, @RequestParam BigDecimal paidAmount,
|
||||
@RequestParam(required = false) String kingdeeAdvanceNo) {
|
||||
preSettlementService.updateAdvancePaidAmount(advanceId, paidAmount, kingdeeAdvanceNo);
|
||||
return R.success("付款金额更新成功");
|
||||
}
|
||||
|
||||
@PostMapping("/void-advance")
|
||||
@ApiOperationSupport(order = 14)
|
||||
@Operation(summary = "作废预付申请")
|
||||
public R voidAdvance(@RequestParam Long advanceId, @RequestParam(required = false) String reason) {
|
||||
preSettlementService.voidAdvance(advanceId, reason);
|
||||
return R.success("预付申请作废成功");
|
||||
}
|
||||
|
||||
@PostMapping("/formal-settlement")
|
||||
@ApiOperationSupport(order = 16)
|
||||
@Operation(summary = "尾款结算")
|
||||
public R<String> formalSettlement(@RequestParam Long id) {
|
||||
return R.data(preSettlementService.formalSettlement(id));
|
||||
}
|
||||
|
||||
@GetMapping("/detail-fees")
|
||||
@ApiOperationSupport(order = 15)
|
||||
@Operation(summary = "结算明细费用")
|
||||
public R<List<PreSettlementDetailFee>> detailFees(@RequestParam Long detailId) {
|
||||
return R.data(preSettlementService.detailFees(detailId));
|
||||
}
|
||||
|
||||
@PostMapping("/adjust-detail")
|
||||
@ApiOperationSupport(order = 17)
|
||||
@Operation(summary = "调整结算明细")
|
||||
public R adjustDetail(@RequestBody PreSettlementDetailAdjustRequest request) {
|
||||
preSettlementService.adjustDetail(request);
|
||||
return R.success("保存成功");
|
||||
}
|
||||
|
||||
@GetMapping("/print-templates")
|
||||
@ApiOperationSupport(order = 18)
|
||||
@Operation(summary = "预结算打印模板")
|
||||
public R<List<Map<String, String>>> printTemplates(@RequestParam Long id) {
|
||||
return R.data(preSettlementService.printTemplates(id));
|
||||
}
|
||||
|
||||
@GetMapping("/export")
|
||||
@ApiOperationSupport(order = 19)
|
||||
@Operation(summary = "导出预结算单")
|
||||
public void export(PreSettlementVO query, HttpServletResponse response) {
|
||||
IPage<PreSettlementVO> page = preSettlementService.selectPage(new Page<>(1, 100000), query);
|
||||
List<PreSettlementExcel> rows = page.getRecords().stream().map(this::toExcel).toList();
|
||||
ExcelUtil.export(response, "预结算单" + DateUtil.time(), "预结算单", rows, PreSettlementExcel.class);
|
||||
}
|
||||
|
||||
private PreSettlementExcel toExcel(PreSettlementVO vo) {
|
||||
PreSettlementExcel excel = new PreSettlementExcel();
|
||||
excel.setPreSettlementNo(vo.getPreSettlementNo());
|
||||
excel.setSourceType(vo.getSourceType());
|
||||
excel.setPayerName(vo.getPayerName());
|
||||
excel.setPayeeName(vo.getPayeeName());
|
||||
excel.setProjectName(vo.getProjectName());
|
||||
excel.setDeptName(vo.getDeptName());
|
||||
excel.setContractNo(vo.getContractNo());
|
||||
excel.setContractName(vo.getContractName());
|
||||
excel.setSettlementAmount(formatMoney(vo.getSettlementAmount(), vo.getCurrency()));
|
||||
excel.setLocalSettlementAmount(formatMoney(vo.getLocalSettlementAmount(), vo.getLocalCurrency()));
|
||||
excel.setExchangeRate(vo.getExchangeRate() == null ? "" : vo.getExchangeRate().stripTrailingZeros().toPlainString());
|
||||
excel.setAdvanceAppliedAmount(formatMoney(vo.getAdvanceAppliedAmount(), vo.getCurrency()));
|
||||
excel.setAdvancePaidAmount(formatMoney(vo.getAdvancePaidAmount(), vo.getCurrency()));
|
||||
excel.setApprovalStatusName(vo.getApprovalStatusName());
|
||||
excel.setCurrentNode(vo.getCurrentNode());
|
||||
excel.setCurrentProcessor(vo.getCurrentProcessor());
|
||||
excel.setCreateUserName(vo.getCreateUserName());
|
||||
excel.setCreateTime(vo.getCreateTime());
|
||||
return excel;
|
||||
}
|
||||
|
||||
private String formatMoney(BigDecimal value, String currency) {
|
||||
if (value == null) return "";
|
||||
return value.setScale(2, RoundingMode.HALF_UP).toPlainString() + " " +
|
||||
(currency == null || currency.isBlank() ? "RMB" : currency);
|
||||
}
|
||||
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* 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.excel;
|
||||
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import cn.idev.excel.annotation.write.style.ColumnWidth;
|
||||
import cn.idev.excel.annotation.write.style.ContentRowHeight;
|
||||
import cn.idev.excel.annotation.write.style.HeadRowHeight;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 预结算单 Excel
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@ColumnWidth(22)
|
||||
@HeadRowHeight(20)
|
||||
@ContentRowHeight(18)
|
||||
public class PreSettlementExcel implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ExcelProperty("预结算单号")
|
||||
private String preSettlementNo;
|
||||
@ExcelProperty("来源")
|
||||
private String sourceType;
|
||||
@ExcelProperty("付款方")
|
||||
private String payerName;
|
||||
@ExcelProperty("收款方")
|
||||
private String payeeName;
|
||||
@ExcelProperty("项目名称")
|
||||
private String projectName;
|
||||
@ExcelProperty("所属组织")
|
||||
private String deptName;
|
||||
@ExcelProperty("合同编号")
|
||||
private String contractNo;
|
||||
@ExcelProperty("合同名称")
|
||||
private String contractName;
|
||||
@ExcelProperty("原币结算金额")
|
||||
private String settlementAmount;
|
||||
@ExcelProperty("本位币结算金额")
|
||||
private String localSettlementAmount;
|
||||
@ExcelProperty("结算汇率")
|
||||
private String exchangeRate;
|
||||
@ExcelProperty("申请预付金额")
|
||||
private String advanceAppliedAmount;
|
||||
@ExcelProperty("已付款金额")
|
||||
private String advancePaidAmount;
|
||||
@ExcelProperty("审核状态")
|
||||
private String approvalStatusName;
|
||||
@ExcelProperty("当前节点")
|
||||
private String currentNode;
|
||||
@ExcelProperty("当前处理人")
|
||||
private String currentProcessor;
|
||||
@ExcelProperty("创建人")
|
||||
private String createUserName;
|
||||
@ExcelProperty("创建时间")
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* 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.apache.ibatis.annotations.Mapper;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlementDetailFee;
|
||||
|
||||
/** 正式结算货物费用 Mapper。 @author Chill */
|
||||
@Mapper
|
||||
public interface FormalSettlementDetailFeeMapper extends BaseMapper<FormalSettlementDetailFee> {
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* 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.apache.ibatis.annotations.Mapper;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlementDetail;
|
||||
|
||||
/** 正式结算明细 Mapper。 @author Chill */
|
||||
@Mapper
|
||||
public interface FormalSettlementDetailMapper extends BaseMapper<FormalSettlementDetail> {
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* 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.apache.ibatis.annotations.Mapper;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlement;
|
||||
|
||||
/** 正式结算单 Mapper。 @author Chill */
|
||||
@Mapper
|
||||
public interface FormalSettlementMapper extends BaseMapper<FormalSettlement> {
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* 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.apache.ibatis.annotations.Mapper;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlementPayment;
|
||||
|
||||
/** 正式结算付款申请 Mapper。 @author Chill */
|
||||
@Mapper
|
||||
public interface FormalSettlementPaymentMapper extends BaseMapper<FormalSettlementPayment> {
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* 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.apache.ibatis.annotations.Mapper;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlementSource;
|
||||
|
||||
/** 正式结算来源 Mapper。 @author Chill */
|
||||
@Mapper
|
||||
public interface FormalSettlementSourceMapper extends BaseMapper<FormalSettlementSource> {
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* 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.apache.ibatis.annotations.Mapper;
|
||||
import org.springblade.transport.pojo.entity.PreSettlementAdvance;
|
||||
|
||||
/**
|
||||
* 预结算预付记录 Mapper
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Mapper
|
||||
public interface PreSettlementAdvanceMapper extends BaseMapper<PreSettlementAdvance> {
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* 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.apache.ibatis.annotations.Mapper;
|
||||
import org.springblade.transport.pojo.entity.PreSettlementChangeRecord;
|
||||
|
||||
/**
|
||||
* 预结算变更记录 Mapper
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Mapper
|
||||
public interface PreSettlementChangeRecordMapper extends BaseMapper<PreSettlementChangeRecord> {
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* 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.apache.ibatis.annotations.Mapper;
|
||||
import org.springblade.transport.pojo.entity.PreSettlementDetailFee;
|
||||
|
||||
/**
|
||||
* 预结算明细费用 Mapper
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Mapper
|
||||
public interface PreSettlementDetailFeeMapper extends BaseMapper<PreSettlementDetailFee> {
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* 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.apache.ibatis.annotations.Mapper;
|
||||
import org.springblade.transport.pojo.entity.PreSettlementDetail;
|
||||
|
||||
/**
|
||||
* 预结算明细 Mapper
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Mapper
|
||||
public interface PreSettlementDetailMapper extends BaseMapper<PreSettlementDetail> {
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* 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.apache.ibatis.annotations.Mapper;
|
||||
import org.springblade.transport.pojo.entity.PreSettlement;
|
||||
|
||||
/**
|
||||
* 预结算单 Mapper
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Mapper
|
||||
public interface PreSettlementMapper extends BaseMapper<PreSettlement> {
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* 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.apache.ibatis.annotations.Mapper;
|
||||
import org.springblade.transport.pojo.entity.PreSettlementSummaryFee;
|
||||
|
||||
/**
|
||||
* 预结算合计费用 Mapper
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Mapper
|
||||
public interface PreSettlementSummaryFeeMapper extends BaseMapper<PreSettlementSummaryFee> {
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* 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.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.springblade.core.mp.base.BaseService;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementSaveRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementStatusRequest;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlement;
|
||||
import org.springblade.transport.pojo.vo.FormalSettlementVO;
|
||||
import org.springblade.transport.pojo.vo.PreSettlementVO;
|
||||
import org.springblade.transport.pojo.entity.PreSettlement;
|
||||
import org.springblade.transport.pojo.dto.PreSettlementDetailAdjustRequest;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlementDetailFee;
|
||||
import java.util.List;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementPaymentRequest;
|
||||
|
||||
/**
|
||||
* 正式结算单服务
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface IFormalSettlementService extends BaseService<FormalSettlement> {
|
||||
IPage<FormalSettlementVO> selectPage(IPage<FormalSettlement> page, FormalSettlementVO query);
|
||||
IPage<PreSettlementVO> candidatePreSettlements(IPage<PreSettlement> page, PreSettlementVO query);
|
||||
FormalSettlementVO detail(Long id);
|
||||
Long saveDraft(FormalSettlementSaveRequest request);
|
||||
void removeDraft(Long id);
|
||||
void submit(FormalSettlementStatusRequest request);
|
||||
void approve(FormalSettlementStatusRequest request);
|
||||
void returnBill(FormalSettlementStatusRequest request);
|
||||
void voidBill(FormalSettlementStatusRequest request);
|
||||
String syncKingdee(Long id);
|
||||
List<FormalSettlementDetailFee> detailFees(Long detailId);
|
||||
void adjustDetail(PreSettlementDetailAdjustRequest request);
|
||||
String applyPayment(FormalSettlementPaymentRequest request);
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* 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.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.springblade.core.mp.base.BaseService;
|
||||
import org.springblade.transport.pojo.dto.PreSettlementAdvanceRequest;
|
||||
import org.springblade.transport.pojo.dto.PreSettlementDetailAdjustRequest;
|
||||
import org.springblade.transport.pojo.dto.PreSettlementSaveRequest;
|
||||
import org.springblade.transport.pojo.dto.PreSettlementStatusRequest;
|
||||
import org.springblade.transport.pojo.entity.PreSettlement;
|
||||
import org.springblade.transport.pojo.entity.PreSettlementDetailFee;
|
||||
import org.springblade.transport.pojo.vo.PreSettlementVO;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 预结算单服务
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface IPreSettlementService extends BaseService<PreSettlement> {
|
||||
|
||||
IPage<PreSettlementVO> selectPage(IPage<PreSettlement> page, PreSettlementVO query);
|
||||
|
||||
PreSettlementVO detail(Long id);
|
||||
|
||||
List<Map<String, Object>> contractOptions(String keyword);
|
||||
|
||||
List<Map<String, Object>> feeOptions();
|
||||
|
||||
IPage<Map<String, Object>> candidateDetails(IPage<?> page, Long contractId, String settlementType,
|
||||
String batchNo, String feeStartDate, String feeEndDate);
|
||||
|
||||
Long saveDraft(PreSettlementSaveRequest request);
|
||||
|
||||
void removeDraft(Long id);
|
||||
|
||||
void removeDetail(Long id, Long detailId);
|
||||
|
||||
void submit(PreSettlementStatusRequest request);
|
||||
|
||||
void approve(PreSettlementStatusRequest request);
|
||||
|
||||
void returnBill(PreSettlementStatusRequest request);
|
||||
|
||||
void voidBill(PreSettlementStatusRequest request);
|
||||
|
||||
void applyAdvance(PreSettlementAdvanceRequest request);
|
||||
|
||||
void updateAdvancePaidAmount(Long advanceId, BigDecimal paidAmount, String kingdeeAdvanceNo);
|
||||
|
||||
void voidAdvance(Long advanceId, String reason);
|
||||
|
||||
String formalSettlement(Long id);
|
||||
|
||||
List<PreSettlementDetailFee> detailFees(Long detailId);
|
||||
|
||||
void adjustDetail(PreSettlementDetailAdjustRequest request);
|
||||
|
||||
List<Map<String, String>> printTemplates(Long id);
|
||||
|
||||
}
|
||||
+511
@@ -0,0 +1,511 @@
|
||||
/**
|
||||
* 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.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springblade.core.log.exception.ServiceException;
|
||||
import org.springblade.core.mp.base.BaseServiceImpl;
|
||||
import org.springblade.core.secure.utils.AuthUtil;
|
||||
import org.springblade.core.tool.utils.BeanUtil;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.transport.mapper.FormalSettlementDetailMapper;
|
||||
import org.springblade.transport.mapper.FormalSettlementDetailFeeMapper;
|
||||
import org.springblade.transport.mapper.FormalSettlementMapper;
|
||||
import org.springblade.transport.mapper.FormalSettlementSourceMapper;
|
||||
import org.springblade.transport.mapper.FormalSettlementPaymentMapper;
|
||||
import org.springblade.transport.mapper.PreSettlementDetailMapper;
|
||||
import org.springblade.transport.mapper.PreSettlementDetailFeeMapper;
|
||||
import org.springblade.transport.mapper.PreSettlementMapper;
|
||||
import org.springblade.transport.mapper.ReceivablePayableDetailMapper;
|
||||
import org.springblade.transport.mapper.ReceivablePayableCargoFeeMapper;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementSaveRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementPaymentRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementStatusRequest;
|
||||
import org.springblade.transport.pojo.dto.PreSettlementDetailAdjustRequest;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlement;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlementDetail;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlementDetailFee;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlementSource;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlementPayment;
|
||||
import org.springblade.transport.pojo.entity.ContractManage;
|
||||
import org.springblade.transport.pojo.entity.PreSettlement;
|
||||
import org.springblade.transport.pojo.entity.PreSettlementDetail;
|
||||
import org.springblade.transport.pojo.entity.PreSettlementDetailFee;
|
||||
import org.springblade.transport.pojo.entity.ReceivablePayableDetail;
|
||||
import org.springblade.transport.pojo.entity.ReceivablePayableCargoFee;
|
||||
import org.springblade.transport.pojo.entity.Waybill;
|
||||
import org.springblade.transport.pojo.vo.FormalSettlementVO;
|
||||
import org.springblade.transport.pojo.vo.PreSettlementVO;
|
||||
import org.springblade.transport.service.IFormalSettlementService;
|
||||
import org.springblade.transport.service.IContractManageService;
|
||||
import org.springblade.transport.service.IWaybillService;
|
||||
import org.springblade.transport.wrapper.PreSettlementWrapper;
|
||||
import org.springblade.core.tool.jackson.JsonUtil;
|
||||
import org.springblade.transport.wrapper.FormalSettlementWrapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 正式结算单服务实现类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class FormalSettlementServiceImpl extends BaseServiceImpl<FormalSettlementMapper, FormalSettlement>
|
||||
implements IFormalSettlementService {
|
||||
|
||||
private static final String DRAFT = "draft";
|
||||
private static final String REVIEWING = "reviewing";
|
||||
private static final String APPROVED = "approved";
|
||||
private static final String RETURNED = "returned";
|
||||
private static final String VOIDED = "voided";
|
||||
private final FormalSettlementSourceMapper sourceMapper;
|
||||
private final FormalSettlementPaymentMapper paymentMapper;
|
||||
private final FormalSettlementDetailMapper detailMapper;
|
||||
private final FormalSettlementDetailFeeMapper detailFeeMapper;
|
||||
private final PreSettlementMapper preSettlementMapper;
|
||||
private final PreSettlementDetailMapper preDetailMapper;
|
||||
private final PreSettlementDetailFeeMapper preDetailFeeMapper;
|
||||
private final ReceivablePayableDetailMapper receivablePayableMapper;
|
||||
private final ReceivablePayableCargoFeeMapper receivablePayableCargoFeeMapper;
|
||||
private final IContractManageService contractManageService;
|
||||
private final IWaybillService waybillService;
|
||||
|
||||
@Override
|
||||
public IPage<FormalSettlementVO> selectPage(IPage<FormalSettlement> page, FormalSettlementVO query) {
|
||||
LambdaQueryWrapper<FormalSettlement> wrapper = Wrappers.<FormalSettlement>lambdaQuery()
|
||||
.like(Func.isNotEmpty(query.getFormalSettlementNo()), FormalSettlement::getFormalSettlementNo, query.getFormalSettlementNo())
|
||||
.like(Func.isNotEmpty(query.getProjectName()), FormalSettlement::getProjectName, query.getProjectName())
|
||||
.like(Func.isNotEmpty(query.getDeptName()), FormalSettlement::getDeptName, query.getDeptName())
|
||||
.like(Func.isNotEmpty(query.getContractNo()), FormalSettlement::getContractNo, query.getContractNo())
|
||||
.like(Func.isNotEmpty(query.getContractName()), FormalSettlement::getContractName, query.getContractName())
|
||||
.like(Func.isNotEmpty(query.getPayerName()), FormalSettlement::getPayerName, query.getPayerName())
|
||||
.like(Func.isNotEmpty(query.getPayeeName()), FormalSettlement::getPayeeName, query.getPayeeName())
|
||||
.eq(Func.isNotEmpty(query.getSettlementType()), FormalSettlement::getSettlementType, query.getSettlementType())
|
||||
.eq(Func.isNotEmpty(query.getInvoiceStatus()), FormalSettlement::getInvoiceStatus, query.getInvoiceStatus())
|
||||
.eq(Func.isNotEmpty(query.getPaymentStatus()), FormalSettlement::getPaymentStatus, query.getPaymentStatus())
|
||||
.eq(Func.isNotEmpty(query.getKingdeeSyncStatus()), FormalSettlement::getKingdeeSyncStatus, query.getKingdeeSyncStatus())
|
||||
.eq(Func.isNotEmpty(query.getApprovalStatus()), FormalSettlement::getApprovalStatus, query.getApprovalStatus())
|
||||
.ge(query.getCreateStartDate() != null, FormalSettlement::getCreateTime, query.getCreateStartDate() == null ? null : query.getCreateStartDate().atStartOfDay())
|
||||
.lt(query.getCreateEndDate() != null, FormalSettlement::getCreateTime, query.getCreateEndDate() == null ? null : query.getCreateEndDate().plusDays(1).atStartOfDay());
|
||||
if (Func.isNotEmpty(query.getPreSettlementNo())) {
|
||||
List<Long> ids = sourceMapper.selectList(Wrappers.<FormalSettlementSource>lambdaQuery()
|
||||
.like(FormalSettlementSource::getPreSettlementNo, query.getPreSettlementNo()))
|
||||
.stream().map(FormalSettlementSource::getFormalSettlementId).distinct().toList();
|
||||
if (ids.isEmpty()) wrapper.eq(FormalSettlement::getId, -1L); else wrapper.in(FormalSettlement::getId, ids);
|
||||
}
|
||||
IPage<FormalSettlement> result = page(page, wrapper.orderByDesc(FormalSettlement::getCreateTime));
|
||||
return result.convert(this::toVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPage<PreSettlementVO> candidatePreSettlements(IPage<PreSettlement> page, PreSettlementVO query) {
|
||||
IPage<PreSettlement> result = preSettlementMapper.selectPage(page, Wrappers.<PreSettlement>lambdaQuery()
|
||||
.eq(PreSettlement::getApprovalStatus, APPROVED)
|
||||
.and(w -> w.isNull(PreSettlement::getFormalSettlementNo).or().eq(PreSettlement::getFormalSettlementNo, ""))
|
||||
.eq(query.getContractId() != null, PreSettlement::getContractId, query.getContractId())
|
||||
.like(Func.isNotEmpty(query.getPreSettlementNo()), PreSettlement::getPreSettlementNo, query.getPreSettlementNo())
|
||||
.like(Func.isNotEmpty(query.getContractNo()), PreSettlement::getContractNo, query.getContractNo())
|
||||
.like(Func.isNotEmpty(query.getContractName()), PreSettlement::getContractName, query.getContractName())
|
||||
.orderByDesc(PreSettlement::getCreateTime));
|
||||
return PreSettlementWrapper.build().pageVO(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FormalSettlementVO detail(Long id) {
|
||||
FormalSettlement settlement = existing(id);
|
||||
FormalSettlementVO vo = toVO(settlement);
|
||||
vo.setSources(sourceMapper.selectList(Wrappers.<FormalSettlementSource>lambdaQuery()
|
||||
.eq(FormalSettlementSource::getFormalSettlementId, id).orderByAsc(FormalSettlementSource::getCreateTime)));
|
||||
vo.setDetails(detailMapper.selectList(Wrappers.<FormalSettlementDetail>lambdaQuery()
|
||||
.eq(FormalSettlementDetail::getFormalSettlementId, id).orderByAsc(FormalSettlementDetail::getLineNo)));
|
||||
vo.setPayments(paymentMapper.selectList(Wrappers.<FormalSettlementPayment>lambdaQuery()
|
||||
.eq(FormalSettlementPayment::getFormalSettlementId, id).orderByDesc(FormalSettlementPayment::getCreateTime)));
|
||||
return vo;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long saveDraft(FormalSettlementSaveRequest request) {
|
||||
if (Func.isEmpty(request.getSourcePreSettlementIds()) && Func.isEmpty(request.getSourceDetailIds())) {
|
||||
throw new ServiceException("请至少选择一张预结算单或一条应收应付明细");
|
||||
}
|
||||
FormalSettlement settlement = request.getId() == null ? new FormalSettlement() : editable(request.getId());
|
||||
if (settlement.getId() != null) releaseSources(settlement);
|
||||
List<PreSettlement> sources = Func.isEmpty(request.getSourcePreSettlementIds()) ? List.of()
|
||||
: request.getSourcePreSettlementIds().stream().distinct().map(this::availableSource).toList();
|
||||
List<ReceivablePayableDetail> directDetails = Func.isEmpty(request.getSourceDetailIds()) ? List.of()
|
||||
: request.getSourceDetailIds().stream().distinct().map(this::availableDetail).toList();
|
||||
Long contractId = sources.isEmpty() ? request.getContractId() : sources.get(0).getContractId();
|
||||
String settlementType = sources.isEmpty() ? request.getSettlementType() : sources.get(0).getSettlementType();
|
||||
if (contractId == null || Func.isEmpty(settlementType)) throw new ServiceException("请选择合同并确认结算类型");
|
||||
if (sources.stream().anyMatch(item -> !Objects.equals(contractId, item.getContractId())
|
||||
|| !Objects.equals(settlementType, item.getSettlementType()))
|
||||
|| directDetails.stream().anyMatch(item -> !Objects.equals(contractId, item.getContractId())
|
||||
|| !Objects.equals(settlementType, item.getSettlementType())
|
||||
|| (!sources.isEmpty() && !Objects.equals(sources.get(0).getCurrency(), item.getCurrency())))) {
|
||||
throw new ServiceException("合并的预结算单必须属于同一合同、结算类型及币种");
|
||||
}
|
||||
PreSettlement first = sources.isEmpty() ? null : sources.get(0);
|
||||
ContractManage contract = contractManageService.getById(contractId);
|
||||
if (contract == null || Objects.equals(contract.getIsDeleted(), 1)) throw new ServiceException("合同不存在");
|
||||
if (settlement.getId() == null) {
|
||||
settlement.setFormalSettlementNo(nextNo());
|
||||
settlement.setApprovalStatus(DRAFT);
|
||||
settlement.setCurrentNode("草稿");
|
||||
settlement.setSourceType(sources.isEmpty() ? "应收应付" : directDetails.isEmpty() ? "预结算合并" : "混合来源");
|
||||
settlement.setInvoiceStatus("unreceived");
|
||||
settlement.setPaymentStatus("unpaid");
|
||||
settlement.setKingdeeSyncStatus("unsynced");
|
||||
}
|
||||
if (first == null) copyHeader(contract, settlementType, directDetails.get(0), settlement); else copyHeader(first, settlement);
|
||||
settlement.setExchangeRateDate(request.getExchangeRateDate());
|
||||
settlement.setExchangeRate(request.getExchangeRate() == null ? BigDecimal.ONE : positive(request.getExchangeRate(), "结算汇率"));
|
||||
BigDecimal sourceAmount = sources.stream().map(PreSettlement::getSettlementAmount).map(this::money).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
BigDecimal detailAmount = directDetails.stream().map(ReceivablePayableDetail::getTotalAmount).map(this::money).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
settlement.setSettlementAmount(sourceAmount.add(detailAmount));
|
||||
settlement.setAppliedPaymentAmount(sources.stream().map(PreSettlement::getAdvanceAppliedAmount)
|
||||
.map(this::money).reduce(BigDecimal.ZERO, BigDecimal::add));
|
||||
settlement.setPaidAmount(sources.stream().map(PreSettlement::getAdvancePaidAmount)
|
||||
.map(this::money).reduce(BigDecimal.ZERO, BigDecimal::add));
|
||||
settlement.setLocalSettlementAmount(settlement.getSettlementAmount().multiply(settlement.getExchangeRate()));
|
||||
settlement.setAttachmentsJson(request.getAttachmentsJson());
|
||||
settlement.setRemark(limit(request.getRemark(), 200));
|
||||
saveOrUpdate(settlement);
|
||||
rebuildSnapshots(settlement, sources, directDetails);
|
||||
return settlement.getId();
|
||||
}
|
||||
|
||||
@Override @Transactional(rollbackFor = Exception.class)
|
||||
public void removeDraft(Long id) {
|
||||
FormalSettlement settlement = editable(id);
|
||||
releaseSources(settlement);
|
||||
sourceMapper.delete(Wrappers.<FormalSettlementSource>lambdaQuery().eq(FormalSettlementSource::getFormalSettlementId, id));
|
||||
List<Long> detailIds = detailMapper.selectList(Wrappers.<FormalSettlementDetail>lambdaQuery()
|
||||
.eq(FormalSettlementDetail::getFormalSettlementId, id)).stream().map(FormalSettlementDetail::getId).toList();
|
||||
if (!detailIds.isEmpty()) detailFeeMapper.delete(Wrappers.<FormalSettlementDetailFee>lambdaQuery()
|
||||
.in(FormalSettlementDetailFee::getFormalSettlementDetailId, detailIds));
|
||||
detailMapper.delete(Wrappers.<FormalSettlementDetail>lambdaQuery().eq(FormalSettlementDetail::getFormalSettlementId, id));
|
||||
removeById(id);
|
||||
}
|
||||
|
||||
@Override public void submit(FormalSettlementStatusRequest request) { changeStatus(request.getId(), DRAFT, REVIEWING, "财务审核", null); }
|
||||
@Override public void returnBill(FormalSettlementStatusRequest request) { changeStatus(request.getId(), REVIEWING, RETURNED, "已驳回", request.getReason()); }
|
||||
|
||||
@Override
|
||||
public void approve(FormalSettlementStatusRequest request) {
|
||||
FormalSettlement settlement = existing(request.getId());
|
||||
if (!REVIEWING.equals(settlement.getApprovalStatus())) throw new ServiceException("仅审批中的正式结算单允许审核");
|
||||
settlement.setApprovalStatus(APPROVED);
|
||||
settlement.setCurrentNode("审批通过");
|
||||
settlement.setCurrentProcessor(AuthUtil.getUserName());
|
||||
settlement.setApprovedTime(LocalDateTime.now());
|
||||
updateById(settlement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void voidBill(FormalSettlementStatusRequest request) {
|
||||
FormalSettlement settlement = existing(request.getId());
|
||||
if (!APPROVED.equals(settlement.getApprovalStatus())) throw new ServiceException("仅审批通过的正式结算单允许作废");
|
||||
if ("synced".equals(settlement.getKingdeeSyncStatus())) throw new ServiceException("已同步金蝶的正式结算单不能直接作废");
|
||||
settlement.setApprovalStatus(VOIDED);
|
||||
settlement.setCurrentNode("已作废");
|
||||
settlement.setVoidReason(required(limit(request.getReason(), 200), "作废原因"));
|
||||
updateById(settlement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String syncKingdee(Long id) {
|
||||
FormalSettlement settlement = existing(id);
|
||||
if (!APPROVED.equals(settlement.getApprovalStatus())) throw new ServiceException("仅审批通过的正式结算单允许同步金蝶");
|
||||
if ("synced".equals(settlement.getKingdeeSyncStatus())) return settlement.getKingdeeBillNo();
|
||||
String kingdeeNo = "K3AP" + DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now());
|
||||
settlement.setKingdeeBillNo(kingdeeNo);
|
||||
settlement.setKingdeeSyncStatus("synced");
|
||||
settlement.setSyncedTime(LocalDateTime.now());
|
||||
updateById(settlement);
|
||||
return kingdeeNo;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String applyPayment(FormalSettlementPaymentRequest request) {
|
||||
FormalSettlement settlement = existing(request.getId());
|
||||
if (!APPROVED.equals(settlement.getApprovalStatus())) throw new ServiceException("仅审批通过的正式结算单允许发起付款申请");
|
||||
if (!"payable".equals(settlement.getSettlementType())) throw new ServiceException("仅应付正式结算单允许发起付款申请");
|
||||
BigDecimal amount = positive(request.getAppliedAmount(), "申请付款金额");
|
||||
BigDecimal available = money(settlement.getSettlementAmount()).subtract(money(settlement.getAppliedPaymentAmount()));
|
||||
if (amount.compareTo(available) > 0) throw new ServiceException("申请付款金额不能超过剩余可申请金额" + available);
|
||||
FormalSettlementPayment payment = new FormalSettlementPayment();
|
||||
payment.setFormalSettlementId(settlement.getId());
|
||||
payment.setPaymentNo(nextPaymentNo());
|
||||
payment.setPaymentType("final");
|
||||
payment.setAppliedAmount(amount);
|
||||
payment.setPaidAmount(BigDecimal.ZERO);
|
||||
payment.setBillStatus(REVIEWING);
|
||||
payment.setRemark(limit(request.getRemark(), 200));
|
||||
paymentMapper.insert(payment);
|
||||
settlement.setAppliedPaymentAmount(money(settlement.getAppliedPaymentAmount()).add(amount));
|
||||
updateById(settlement);
|
||||
return payment.getPaymentNo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FormalSettlementDetailFee> detailFees(Long detailId) {
|
||||
FormalSettlementDetail detail = detailMapper.selectById(detailId);
|
||||
if (detail == null || Objects.equals(detail.getIsDeleted(), 1)) throw new ServiceException("正式结算明细不存在");
|
||||
return detailFeeMapper.selectList(Wrappers.<FormalSettlementDetailFee>lambdaQuery()
|
||||
.eq(FormalSettlementDetailFee::getFormalSettlementDetailId, detailId)
|
||||
.orderByAsc(FormalSettlementDetailFee::getLineNo));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void adjustDetail(PreSettlementDetailAdjustRequest request) {
|
||||
FormalSettlementDetail detail = detailMapper.selectById(request.getDetailId());
|
||||
if (detail == null || Objects.equals(detail.getIsDeleted(), 1)) throw new ServiceException("正式结算明细不存在");
|
||||
FormalSettlement settlement = editable(detail.getFormalSettlementId());
|
||||
if (Func.isEmpty(request.getRows())) throw new ServiceException("请填写需要调整的货物费用行");
|
||||
String reason = required(limit(request.getChangeReason(), 200), "调整原因");
|
||||
Map<Long, FormalSettlementDetailFee> existing = detailFees(detail.getId()).stream()
|
||||
.collect(Collectors.toMap(FormalSettlementDetailFee::getId, item -> item));
|
||||
if (existing.size() != request.getRows().size()) throw new ServiceException("费用调整行数据不完整");
|
||||
for (PreSettlementDetailAdjustRequest.FeeRow row : request.getRows()) {
|
||||
FormalSettlementDetailFee fee = existing.get(row.getId());
|
||||
if (fee == null) throw new ServiceException("存在无效的货物费用行");
|
||||
fee.setTransportQuantity(nonNegative(row.getTransportQuantity(), "运输总量"));
|
||||
fee.setMileage(nonNegative(row.getMileage(), "里程"));
|
||||
fee.setUnitPrice(nonNegative(row.getUnitPrice(), "运输单价"));
|
||||
fee.setFreightAmount(nonNegative(row.getFreightAmount(), "运费"));
|
||||
fee.setFeeItemsJson(JsonUtil.toJson(row.getFeeItems() == null ? java.util.Map.of() : row.getFeeItems()));
|
||||
fee.setSettlementAmountTax(nonNegative(row.getSettlementAmountTax(), "结算金额(含税)"));
|
||||
fee.setSettlementAmountNoTax(row.getSettlementAmountNoTax() == null ? null : nonNegative(row.getSettlementAmountNoTax(), "结算金额(不含税)"));
|
||||
fee.setAdjustAmount(fee.getSettlementAmountTax().subtract(money(fee.getOriginalAmount())));
|
||||
fee.setRemark(limit(row.getRemark(), 200));
|
||||
detailFeeMapper.updateById(fee);
|
||||
}
|
||||
List<FormalSettlementDetailFee> rows = detailFees(detail.getId());
|
||||
detail.setTransportQuantity(rows.stream().map(FormalSettlementDetailFee::getTransportQuantity).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add));
|
||||
detail.setFreightAmount(rows.stream().map(FormalSettlementDetailFee::getFreightAmount).map(this::money).reduce(BigDecimal.ZERO, BigDecimal::add));
|
||||
detail.setOriginalAmount(rows.stream().map(FormalSettlementDetailFee::getOriginalAmount).map(this::money).reduce(BigDecimal.ZERO, BigDecimal::add));
|
||||
detail.setSettlementAmountTax(rows.stream().map(FormalSettlementDetailFee::getSettlementAmountTax).map(this::money).reduce(BigDecimal.ZERO, BigDecimal::add));
|
||||
detail.setSettlementAmountNoTax(rows.stream().map(FormalSettlementDetailFee::getSettlementAmountNoTax).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add));
|
||||
detail.setAdjustAmount(detail.getSettlementAmountTax().subtract(detail.getOriginalAmount()));
|
||||
detail.setRemark(reason);
|
||||
detailMapper.updateById(detail);
|
||||
BigDecimal amount = detailMapper.selectList(Wrappers.<FormalSettlementDetail>lambdaQuery()
|
||||
.eq(FormalSettlementDetail::getFormalSettlementId, settlement.getId())).stream()
|
||||
.map(FormalSettlementDetail::getSettlementAmountTax).map(this::money).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
settlement.setSettlementAmount(amount);
|
||||
settlement.setLocalSettlementAmount(amount.multiply(settlement.getExchangeRate() == null ? BigDecimal.ONE : settlement.getExchangeRate()));
|
||||
updateById(settlement);
|
||||
}
|
||||
|
||||
private void rebuildSnapshots(FormalSettlement settlement, List<PreSettlement> sources, List<ReceivablePayableDetail> directDetails) {
|
||||
List<Long> existingDetailIds = detailMapper.selectList(Wrappers.<FormalSettlementDetail>lambdaQuery()
|
||||
.eq(FormalSettlementDetail::getFormalSettlementId, settlement.getId())).stream().map(FormalSettlementDetail::getId).toList();
|
||||
if (!existingDetailIds.isEmpty()) detailFeeMapper.delete(Wrappers.<FormalSettlementDetailFee>lambdaQuery()
|
||||
.in(FormalSettlementDetailFee::getFormalSettlementDetailId, existingDetailIds));
|
||||
sourceMapper.delete(Wrappers.<FormalSettlementSource>lambdaQuery().eq(FormalSettlementSource::getFormalSettlementId, settlement.getId()));
|
||||
detailMapper.delete(Wrappers.<FormalSettlementDetail>lambdaQuery().eq(FormalSettlementDetail::getFormalSettlementId, settlement.getId()));
|
||||
int lineNo = 1;
|
||||
for (PreSettlement source : sources) {
|
||||
FormalSettlementSource relation = new FormalSettlementSource();
|
||||
relation.setFormalSettlementId(settlement.getId()); relation.setPreSettlementId(source.getId());
|
||||
relation.setPreSettlementNo(source.getPreSettlementNo()); relation.setSettlementAmount(source.getSettlementAmount());
|
||||
relation.setAdvanceAppliedAmount(source.getAdvanceAppliedAmount()); relation.setAdvancePaidAmount(source.getAdvancePaidAmount());
|
||||
sourceMapper.insert(relation);
|
||||
int reserved = preSettlementMapper.update(null, Wrappers.<PreSettlement>lambdaUpdate()
|
||||
.eq(PreSettlement::getId, source.getId())
|
||||
.eq(PreSettlement::getApprovalStatus, APPROVED)
|
||||
.and(w -> w.isNull(PreSettlement::getFormalSettlementNo).or().eq(PreSettlement::getFormalSettlementNo, ""))
|
||||
.set(PreSettlement::getFormalSettlementNo, settlement.getFormalSettlementNo())
|
||||
.set(PreSettlement::getFormalSettledTime, LocalDateTime.now())
|
||||
.set(PreSettlement::getCurrentNode, "已锁定(正式结算)"));
|
||||
if (reserved != 1) throw new ServiceException("预结算单" + source.getPreSettlementNo() + "已被其他正式结算占用");
|
||||
for (PreSettlementDetail item : preDetailMapper.selectList(Wrappers.<PreSettlementDetail>lambdaQuery().eq(PreSettlementDetail::getPreSettlementId, source.getId()))) {
|
||||
FormalSettlementDetail detail = Objects.requireNonNull(BeanUtil.copyProperties(item, FormalSettlementDetail.class));
|
||||
detail.setId(null); detail.setFormalSettlementId(settlement.getId()); detail.setSourcePreSettlementId(source.getId());
|
||||
detail.setSourcePreSettlementDetailId(item.getId()); detail.setLineNo(lineNo++); detailMapper.insert(detail);
|
||||
copyPreDetailFees(item, detail);
|
||||
ReceivablePayableDetail original = receivablePayableMapper.selectById(item.getSourceDetailId());
|
||||
if (original != null) { original.setFormalSettlementNo(settlement.getFormalSettlementNo()); original.setSettlementStatus("formal_settled"); receivablePayableMapper.updateById(original); }
|
||||
}
|
||||
}
|
||||
for (ReceivablePayableDetail source : directDetails) {
|
||||
FormalSettlementDetail detail = new FormalSettlementDetail();
|
||||
detail.setFormalSettlementId(settlement.getId()); detail.setSourceDetailId(source.getId()); detail.setLineNo(lineNo++);
|
||||
detail.setDocumentNo(source.getDocumentNo()); detail.setWaybillId(source.getWaybillId()); detail.setWaybillNo(source.getWaybillNo());
|
||||
detail.setVehicleNo(source.getVehicleNo()); detail.setTransportType(source.getTransportType()); detail.setCargoName(source.getCargoName());
|
||||
detail.setCargoType(source.getCargoType()); detail.setTransportQuantity(source.getTransportQuantity()); detail.setQuantityUnit(source.getQuantityUnit());
|
||||
detail.setMileage(source.getMileage()); detail.setBatchNo(source.getBatchNo()); detail.setUnitPrice(source.getUnitPrice());
|
||||
detail.setFreightAmount(money(source.getFreightAmount())); detail.setFeeItemsJson(source.getFeeItemsJson());
|
||||
detail.setOriginalAmount(money(source.getTotalAmount())); detail.setAdjustAmount(BigDecimal.ZERO);
|
||||
detail.setSettlementAmountTax(money(source.getTotalAmount())); detail.setCurrency(Func.isEmpty(source.getCurrency()) ? "RMB" : source.getCurrency());
|
||||
Waybill waybill = source.getWaybillId() == null ? null : waybillService.getById(source.getWaybillId());
|
||||
if (waybill != null) {
|
||||
detail.setDepartureAddress(Func.isNotEmpty(waybill.getDepartureAddress()) ? waybill.getDepartureAddress() : waybill.getDepartureName());
|
||||
detail.setArrivalAddress(Func.isNotEmpty(waybill.getArrivalAddress()) ? waybill.getArrivalAddress() : waybill.getArrivalName());
|
||||
detail.setActualDepartureTime(waybill.getStartDate() == null ? null : waybill.getStartDate().atStartOfDay());
|
||||
detail.setActualCompletionTime(waybill.getEndDate() == null ? null : waybill.getEndDate().atStartOfDay());
|
||||
}
|
||||
detail.setRemark(source.getRemark()); detailMapper.insert(detail);
|
||||
copyDirectDetailFees(source, detail);
|
||||
int affected = receivablePayableMapper.update(null, Wrappers.<ReceivablePayableDetail>lambdaUpdate()
|
||||
.eq(ReceivablePayableDetail::getId, source.getId())
|
||||
.eq(ReceivablePayableDetail::getSettlementStatus, "pending")
|
||||
.and(w -> w.isNull(ReceivablePayableDetail::getPreSettlementNo).or().eq(ReceivablePayableDetail::getPreSettlementNo, ""))
|
||||
.and(w -> w.isNull(ReceivablePayableDetail::getFormalSettlementNo).or().eq(ReceivablePayableDetail::getFormalSettlementNo, ""))
|
||||
.set(ReceivablePayableDetail::getFormalSettlementNo, settlement.getFormalSettlementNo())
|
||||
.set(ReceivablePayableDetail::getSettlementStatus, "formal_settled"));
|
||||
if (affected != 1) throw new ServiceException("单据" + source.getDocumentNo() + "已被其他结算单选择");
|
||||
}
|
||||
}
|
||||
|
||||
private void copyPreDetailFees(PreSettlementDetail source, FormalSettlementDetail target) {
|
||||
List<PreSettlementDetailFee> fees = preDetailFeeMapper.selectList(Wrappers.<PreSettlementDetailFee>lambdaQuery()
|
||||
.eq(PreSettlementDetailFee::getPreSettlementDetailId, source.getId()).orderByAsc(PreSettlementDetailFee::getLineNo));
|
||||
for (PreSettlementDetailFee item : fees) {
|
||||
FormalSettlementDetailFee fee = Objects.requireNonNull(BeanUtil.copyProperties(item, FormalSettlementDetailFee.class));
|
||||
fee.setId(null); fee.setFormalSettlementDetailId(target.getId()); fee.setSourceFeeId(item.getId()); detailFeeMapper.insert(fee);
|
||||
}
|
||||
if (fees.isEmpty()) createSingleFee(target);
|
||||
}
|
||||
|
||||
private void copyDirectDetailFees(ReceivablePayableDetail source, FormalSettlementDetail target) {
|
||||
List<ReceivablePayableCargoFee> fees = receivablePayableCargoFeeMapper.selectList(Wrappers.<ReceivablePayableCargoFee>lambdaQuery()
|
||||
.eq(ReceivablePayableCargoFee::getDetailId, source.getId()).orderByAsc(ReceivablePayableCargoFee::getLineNo));
|
||||
for (ReceivablePayableCargoFee item : fees) {
|
||||
FormalSettlementDetailFee fee = Objects.requireNonNull(BeanUtil.copyProperties(item, FormalSettlementDetailFee.class));
|
||||
fee.setId(null); fee.setFormalSettlementDetailId(target.getId()); fee.setSourceFeeId(item.getId());
|
||||
fee.setSettlementAmountTax(item.getAfterAmount() == null ? money(item.getOriginalAmount()) : item.getAfterAmount());
|
||||
fee.setSettlementAmountNoTax(null); detailFeeMapper.insert(fee);
|
||||
}
|
||||
if (fees.isEmpty()) createSingleFee(target);
|
||||
}
|
||||
|
||||
private void createSingleFee(FormalSettlementDetail target) {
|
||||
FormalSettlementDetailFee fee = Objects.requireNonNull(BeanUtil.copyProperties(target, FormalSettlementDetailFee.class));
|
||||
fee.setId(null); fee.setFormalSettlementDetailId(target.getId()); fee.setLineNo("0001"); detailFeeMapper.insert(fee);
|
||||
}
|
||||
|
||||
private void releaseSources(FormalSettlement settlement) {
|
||||
for (FormalSettlementSource relation : sourceMapper.selectList(Wrappers.<FormalSettlementSource>lambdaQuery().eq(FormalSettlementSource::getFormalSettlementId, settlement.getId()))) {
|
||||
PreSettlement source = preSettlementMapper.selectById(relation.getPreSettlementId());
|
||||
if (source != null && Objects.equals(source.getFormalSettlementNo(), settlement.getFormalSettlementNo())) {
|
||||
preSettlementMapper.update(null, Wrappers.<PreSettlement>lambdaUpdate()
|
||||
.eq(PreSettlement::getId, source.getId())
|
||||
.set(PreSettlement::getFormalSettlementNo, null)
|
||||
.set(PreSettlement::getFormalSettledTime, null)
|
||||
.set(PreSettlement::getCurrentNode, "审批通过"));
|
||||
}
|
||||
}
|
||||
for (FormalSettlementDetail detail : detailMapper.selectList(Wrappers.<FormalSettlementDetail>lambdaQuery().eq(FormalSettlementDetail::getFormalSettlementId, settlement.getId()))) {
|
||||
ReceivablePayableDetail source = receivablePayableMapper.selectById(detail.getSourceDetailId());
|
||||
if (source != null && Objects.equals(source.getFormalSettlementNo(), settlement.getFormalSettlementNo())) {
|
||||
receivablePayableMapper.update(null, Wrappers.<ReceivablePayableDetail>lambdaUpdate()
|
||||
.eq(ReceivablePayableDetail::getId, source.getId())
|
||||
.set(ReceivablePayableDetail::getFormalSettlementNo, null)
|
||||
.set(ReceivablePayableDetail::getSettlementStatus,
|
||||
detail.getSourcePreSettlementId() == null ? "pending" : "pre_settled"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private FormalSettlementVO toVO(FormalSettlement entity) {
|
||||
FormalSettlementVO vo = FormalSettlementWrapper.build().entityVO(entity);
|
||||
vo.setPreSettlementNos(sourceMapper.selectList(Wrappers.<FormalSettlementSource>lambdaQuery().eq(FormalSettlementSource::getFormalSettlementId, entity.getId())).stream().map(FormalSettlementSource::getPreSettlementNo).collect(Collectors.joining(",")));
|
||||
return vo;
|
||||
}
|
||||
|
||||
private PreSettlement availableSource(Long id) {
|
||||
PreSettlement source = preSettlementMapper.selectById(id);
|
||||
if (source == null || Objects.equals(source.getIsDeleted(), 1)) throw new ServiceException("预结算单不存在");
|
||||
if (!APPROVED.equals(source.getApprovalStatus())) throw new ServiceException("仅审批通过的预结算单可生成正式结算");
|
||||
if (Func.isNotEmpty(source.getFormalSettlementNo())) throw new ServiceException("预结算单" + source.getPreSettlementNo() + "已被正式结算占用");
|
||||
return source;
|
||||
}
|
||||
|
||||
private ReceivablePayableDetail availableDetail(Long id) {
|
||||
ReceivablePayableDetail detail = receivablePayableMapper.selectById(id);
|
||||
if (detail == null || Objects.equals(detail.getIsDeleted(), 1)) throw new ServiceException("应收应付明细不存在");
|
||||
if (!"pending".equals(detail.getSettlementStatus()) || Func.isNotEmpty(detail.getPreSettlementNo()) || Func.isNotEmpty(detail.getFormalSettlementNo())) {
|
||||
throw new ServiceException("单据" + detail.getDocumentNo() + "已被结算或关闭");
|
||||
}
|
||||
return detail;
|
||||
}
|
||||
|
||||
private FormalSettlement existing(Long id) {
|
||||
FormalSettlement entity = getById(id);
|
||||
if (entity == null || Objects.equals(entity.getIsDeleted(), 1)) throw new ServiceException("正式结算单不存在");
|
||||
return entity;
|
||||
}
|
||||
|
||||
private FormalSettlement editable(Long id) {
|
||||
FormalSettlement entity = existing(id);
|
||||
if (!DRAFT.equals(entity.getApprovalStatus()) && !RETURNED.equals(entity.getApprovalStatus())) throw new ServiceException("仅草稿或已驳回的正式结算单允许编辑");
|
||||
return entity;
|
||||
}
|
||||
|
||||
private void changeStatus(Long id, String expected, String target, String node, String reason) {
|
||||
FormalSettlement settlement = existing(id);
|
||||
if (!expected.equals(settlement.getApprovalStatus()) && !(DRAFT.equals(expected) && RETURNED.equals(settlement.getApprovalStatus()))) throw new ServiceException("当前状态不允许该操作");
|
||||
settlement.setApprovalStatus(target); settlement.setCurrentNode(node); settlement.setCurrentProcessor(AuthUtil.getUserName());
|
||||
if (RETURNED.equals(target)) settlement.setVoidReason(limit(reason, 200));
|
||||
updateById(settlement);
|
||||
}
|
||||
|
||||
private void copyHeader(PreSettlement source, FormalSettlement target) {
|
||||
target.setSettlementType(source.getSettlementType()); target.setProjectId(source.getProjectId()); target.setProjectName(source.getProjectName());
|
||||
target.setDeptId(source.getDeptId()); target.setDeptName(source.getDeptName()); target.setContractId(source.getContractId()); target.setContractNo(source.getContractNo());
|
||||
target.setContractName(source.getContractName()); target.setPayerName(source.getPayerName()); target.setPayeeName(source.getPayeeName());
|
||||
target.setCurrency(source.getCurrency()); target.setLocalCurrency(source.getLocalCurrency());
|
||||
}
|
||||
|
||||
private void copyHeader(ContractManage contract, String settlementType, ReceivablePayableDetail source, FormalSettlement target) {
|
||||
target.setSettlementType(settlementType); target.setProjectId(contract.getProjectId()); target.setProjectName(contract.getProjectName());
|
||||
target.setDeptId(contract.getOrganizationId()); target.setDeptName(contract.getOrganizationName()); target.setContractId(contract.getId());
|
||||
target.setContractNo(contract.getContractNo()); target.setContractName(contract.getContractName());
|
||||
if ("receivable".equals(settlementType)) { target.setPayerName(source.getCustomerName()); target.setPayeeName(contract.getPartyA()); }
|
||||
else { target.setPayerName(contract.getPartyA()); target.setPayeeName(source.getCustomerName()); }
|
||||
target.setCurrency(Func.isEmpty(source.getCurrency()) ? "RMB" : source.getCurrency()); target.setLocalCurrency("RMB");
|
||||
}
|
||||
|
||||
private synchronized String nextNo() {
|
||||
String prefix = "JS" + LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE);
|
||||
long count = count(Wrappers.<FormalSettlement>lambdaQuery().likeRight(FormalSettlement::getFormalSettlementNo, prefix));
|
||||
return prefix + String.format("%04d", count + 1);
|
||||
}
|
||||
|
||||
private synchronized String nextPaymentNo() {
|
||||
String prefix = "FK" + LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE);
|
||||
long count = paymentMapper.selectCount(Wrappers.<FormalSettlementPayment>lambdaQuery()
|
||||
.likeRight(FormalSettlementPayment::getPaymentNo, prefix));
|
||||
return prefix + String.format("%04d", count + 1);
|
||||
}
|
||||
|
||||
private BigDecimal money(BigDecimal value) { return value == null ? BigDecimal.ZERO : value; }
|
||||
private BigDecimal nonNegative(BigDecimal value, String field) { if (value == null || value.signum() < 0) throw new ServiceException(field + "不能小于0"); return value; }
|
||||
private BigDecimal positive(BigDecimal value, String field) { if (value == null || value.signum() <= 0) throw new ServiceException(field + "必须大于0"); return value; }
|
||||
private String required(String value, String field) { if (Func.isEmpty(value)) throw new ServiceException("请填写" + field); return value; }
|
||||
private String limit(String value, int max) { if (value != null && value.length() > max) throw new ServiceException("内容不能超过" + max + "个字"); return value; }
|
||||
}
|
||||
+1404
File diff suppressed because it is too large
Load Diff
+45
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* 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.wrapper;
|
||||
|
||||
import org.springblade.core.mp.support.BaseEntityWrapper;
|
||||
import org.springblade.core.tool.utils.BeanUtil;
|
||||
import org.springblade.system.cache.UserCache;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlement;
|
||||
import org.springblade.transport.pojo.vo.FormalSettlementVO;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 正式结算单包装类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public class FormalSettlementWrapper extends BaseEntityWrapper<FormalSettlement, FormalSettlementVO> {
|
||||
|
||||
public static FormalSettlementWrapper build() {
|
||||
return new FormalSettlementWrapper();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FormalSettlementVO entityVO(FormalSettlement entity) {
|
||||
FormalSettlementVO vo = Objects.requireNonNull(BeanUtil.copyProperties(entity, FormalSettlementVO.class));
|
||||
vo.setCreateUserName(UserCache.getUserRealName(entity.getCreateUser()));
|
||||
vo.setSettlementTypeName("receivable".equals(entity.getSettlementType()) ? "应收" : "应付");
|
||||
vo.setApprovalStatusName(switch (entity.getApprovalStatus() == null ? "" : entity.getApprovalStatus()) {
|
||||
case "draft" -> "草稿";
|
||||
case "reviewing" -> "审批中";
|
||||
case "approved" -> "审批通过";
|
||||
case "returned" -> "已驳回";
|
||||
case "voided" -> "已作废";
|
||||
default -> entity.getApprovalStatus();
|
||||
});
|
||||
return vo;
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* 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.wrapper;
|
||||
|
||||
import org.springblade.core.mp.support.BaseEntityWrapper;
|
||||
import org.springblade.core.tool.utils.BeanUtil;
|
||||
import org.springblade.system.cache.UserCache;
|
||||
import org.springblade.transport.pojo.entity.PreSettlement;
|
||||
import org.springblade.transport.pojo.vo.PreSettlementVO;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 预结算单包装类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public class PreSettlementWrapper extends BaseEntityWrapper<PreSettlement, PreSettlementVO> {
|
||||
|
||||
public static PreSettlementWrapper build() {
|
||||
return new PreSettlementWrapper();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreSettlementVO entityVO(PreSettlement entity) {
|
||||
PreSettlementVO vo = Objects.requireNonNull(BeanUtil.copyProperties(entity, PreSettlementVO.class));
|
||||
vo.setCreateUserName(UserCache.getUserRealName(entity.getCreateUser()));
|
||||
vo.setUpdateUserName(UserCache.getUserRealName(entity.getUpdateUser()));
|
||||
vo.setApprovalStatusName(approvalStatusName(entity.getApprovalStatus()));
|
||||
vo.setSettlementTypeName("receivable".equals(entity.getSettlementType()) ? "应收" : "应付");
|
||||
return vo;
|
||||
}
|
||||
|
||||
private String approvalStatusName(String status) {
|
||||
return switch (status == null ? "" : status) {
|
||||
case "draft" -> "草稿";
|
||||
case "reviewing" -> "审批中";
|
||||
case "approved" -> "审批通过";
|
||||
case "returned" -> "已驳回";
|
||||
case "voided" -> "已作废";
|
||||
default -> status;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
-- 结算管理 / 正式结算单
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `blade_formal_settlement` (
|
||||
`id` bigint(20) NOT NULL COMMENT '主键', `tenant_id` varchar(12) NOT NULL DEFAULT '000000' COMMENT '租户ID',
|
||||
`create_user` bigint(20) DEFAULT NULL, `create_dept` bigint(20) DEFAULT NULL, `create_time` datetime DEFAULT NULL,
|
||||
`update_user` bigint(20) DEFAULT NULL, `update_time` datetime DEFAULT NULL, `status` int(11) DEFAULT '1', `is_deleted` int(11) DEFAULT '0',
|
||||
`formal_settlement_no` varchar(100) NOT NULL COMMENT '正式结算单号', `source_type` varchar(30) NOT NULL DEFAULT '预结算合并',
|
||||
`settlement_type` varchar(30) NOT NULL, `project_id` bigint(20) DEFAULT NULL, `project_name` varchar(100) DEFAULT NULL,
|
||||
`dept_id` bigint(20) DEFAULT NULL, `dept_name` varchar(100) DEFAULT NULL, `contract_id` bigint(20) NOT NULL,
|
||||
`contract_no` varchar(100) DEFAULT NULL, `contract_name` varchar(100) NOT NULL, `payer_name` varchar(200) DEFAULT NULL,
|
||||
`payee_name` varchar(200) DEFAULT NULL, `currency` varchar(20) NOT NULL DEFAULT 'RMB', `settlement_amount` decimal(18,2) NOT NULL DEFAULT '0.00',
|
||||
`local_currency` varchar(20) NOT NULL DEFAULT 'RMB', `local_settlement_amount` decimal(18,2) DEFAULT NULL,
|
||||
`applied_payment_amount` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '申请付款金额含预付',
|
||||
`paid_amount` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '已收已付合计',
|
||||
`exchange_rate_date` date DEFAULT NULL, `exchange_rate` decimal(18,6) DEFAULT NULL,
|
||||
`invoice_status` varchar(30) NOT NULL DEFAULT 'unreceived', `payment_status` varchar(30) NOT NULL DEFAULT 'unpaid',
|
||||
`approval_status` varchar(30) NOT NULL DEFAULT 'draft', `current_node` varchar(100) DEFAULT NULL, `current_processor` varchar(200) DEFAULT NULL,
|
||||
`kingdee_bill_no` varchar(100) DEFAULT NULL, `kingdee_sync_status` varchar(30) NOT NULL DEFAULT 'unsynced',
|
||||
`attachments_json` longtext, `remark` varchar(200) DEFAULT NULL, `approved_time` datetime DEFAULT NULL, `synced_time` datetime DEFAULT NULL,
|
||||
`void_reason` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_formal_settlement_no` (`tenant_id`,`formal_settlement_no`),
|
||||
KEY `idx_formal_contract` (`contract_id`), KEY `idx_formal_approval` (`approval_status`), KEY `idx_formal_create_time` (`create_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='正式结算单';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `blade_formal_settlement_source` (
|
||||
`id` bigint(20) NOT NULL, `tenant_id` varchar(12) NOT NULL DEFAULT '000000', `create_user` bigint(20) DEFAULT NULL,
|
||||
`create_dept` bigint(20) DEFAULT NULL, `create_time` datetime DEFAULT NULL, `update_user` bigint(20) DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL, `status` int(11) DEFAULT '1', `is_deleted` int(11) DEFAULT '0',
|
||||
`formal_settlement_id` bigint(20) NOT NULL, `pre_settlement_id` bigint(20) NOT NULL, `pre_settlement_no` varchar(100) NOT NULL,
|
||||
`settlement_amount` decimal(18,2) NOT NULL DEFAULT '0.00', `advance_applied_amount` decimal(18,2) NOT NULL DEFAULT '0.00',
|
||||
`advance_paid_amount` decimal(18,2) NOT NULL DEFAULT '0.00', PRIMARY KEY (`id`),
|
||||
KEY `idx_formal_source_pre` (`pre_settlement_id`), KEY `idx_formal_source_bill` (`formal_settlement_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='正式结算来源预结算';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `blade_formal_settlement_detail` (
|
||||
`id` bigint(20) NOT NULL, `tenant_id` varchar(12) NOT NULL DEFAULT '000000', `create_user` bigint(20) DEFAULT NULL,
|
||||
`create_dept` bigint(20) DEFAULT NULL, `create_time` datetime DEFAULT NULL, `update_user` bigint(20) DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL, `status` int(11) DEFAULT '1', `is_deleted` int(11) DEFAULT '0',
|
||||
`formal_settlement_id` bigint(20) NOT NULL, `source_pre_settlement_id` bigint(20) DEFAULT NULL,
|
||||
`source_pre_settlement_detail_id` bigint(20) DEFAULT NULL, `source_detail_id` bigint(20) NOT NULL, `line_no` int(11) NOT NULL,
|
||||
`document_no` varchar(100) DEFAULT NULL, `waybill_id` bigint(20) DEFAULT NULL, `waybill_no` varchar(100) DEFAULT NULL,
|
||||
`vehicle_no` varchar(100) DEFAULT NULL, `departure_address` varchar(500) DEFAULT NULL, `arrival_address` varchar(500) DEFAULT NULL,
|
||||
`actual_departure_time` datetime DEFAULT NULL, `actual_completion_time` datetime DEFAULT NULL, `transport_type` varchar(100) DEFAULT NULL,
|
||||
`cargo_name` varchar(500) DEFAULT NULL, `cargo_type` varchar(500) DEFAULT NULL, `transport_quantity` decimal(18,6) DEFAULT NULL,
|
||||
`quantity_unit` varchar(50) DEFAULT NULL, `mileage` decimal(18,2) DEFAULT NULL, `batch_no` varchar(100) DEFAULT NULL,
|
||||
`unit_price` decimal(18,2) DEFAULT NULL, `freight_amount` decimal(18,2) NOT NULL DEFAULT '0.00', `fee_items_json` longtext,
|
||||
`original_amount` decimal(18,2) NOT NULL DEFAULT '0.00', `adjust_amount` decimal(18,2) NOT NULL DEFAULT '0.00',
|
||||
`settlement_amount_tax` decimal(18,2) NOT NULL DEFAULT '0.00', `settlement_amount_no_tax` decimal(18,2) DEFAULT NULL,
|
||||
`currency` varchar(20) NOT NULL DEFAULT 'RMB', `remark` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`),
|
||||
KEY `idx_formal_detail_bill` (`formal_settlement_id`), KEY `idx_formal_detail_source` (`source_detail_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='正式结算明细快照';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `blade_formal_settlement_detail_fee` (
|
||||
`id` bigint(20) NOT NULL, `tenant_id` varchar(12) NOT NULL DEFAULT '000000', `create_user` bigint(20) DEFAULT NULL,
|
||||
`create_dept` bigint(20) DEFAULT NULL, `create_time` datetime DEFAULT NULL, `update_user` bigint(20) DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL, `status` int(11) DEFAULT '1', `is_deleted` int(11) DEFAULT '0',
|
||||
`formal_settlement_detail_id` bigint(20) NOT NULL, `source_fee_id` bigint(20) DEFAULT NULL, `line_no` varchar(30) DEFAULT NULL,
|
||||
`cargo_name` varchar(100) DEFAULT NULL, `cargo_type` varchar(100) DEFAULT NULL, `transport_quantity` decimal(18,6) DEFAULT NULL,
|
||||
`quantity_unit` varchar(50) DEFAULT NULL, `mileage` decimal(18,2) DEFAULT NULL, `unit_price` decimal(18,2) DEFAULT NULL,
|
||||
`freight_amount` decimal(18,2) NOT NULL DEFAULT '0.00', `fee_items_json` longtext, `original_amount` decimal(18,2) NOT NULL DEFAULT '0.00',
|
||||
`adjust_amount` decimal(18,2) NOT NULL DEFAULT '0.00', `settlement_amount_tax` decimal(18,2) NOT NULL DEFAULT '0.00',
|
||||
`settlement_amount_no_tax` decimal(18,2) DEFAULT NULL, `remark` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`),
|
||||
KEY `idx_formal_detail_fee_detail` (`formal_settlement_detail_id`), KEY `idx_formal_detail_fee_source` (`source_fee_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='正式结算货物费用快照';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `blade_formal_settlement_payment` (
|
||||
`id` bigint(20) NOT NULL, `tenant_id` varchar(12) NOT NULL DEFAULT '000000', `create_user` bigint(20) DEFAULT NULL,
|
||||
`create_dept` bigint(20) DEFAULT NULL, `create_time` datetime DEFAULT NULL, `update_user` bigint(20) DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL, `status` int(11) DEFAULT '1', `is_deleted` int(11) DEFAULT '0',
|
||||
`formal_settlement_id` bigint(20) NOT NULL, `payment_no` varchar(100) NOT NULL, `payment_type` varchar(30) NOT NULL DEFAULT 'final',
|
||||
`applied_amount` decimal(18,2) NOT NULL DEFAULT '0.00', `paid_amount` decimal(18,2) NOT NULL DEFAULT '0.00',
|
||||
`bill_status` varchar(30) NOT NULL DEFAULT 'reviewing', `kingdee_bill_no` varchar(100) DEFAULT NULL, `remark` varchar(200) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`), UNIQUE KEY `uk_formal_payment_no` (`tenant_id`,`payment_no`),
|
||||
KEY `idx_formal_payment_bill` (`formal_settlement_id`), KEY `idx_formal_payment_status` (`bill_status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='正式结算付款申请';
|
||||
|
||||
INSERT INTO `blade_menu` (`id`,`parent_id`,`code`,`name`,`alias`,`path`,`source`,`sort`,`category`,`action`,`is_open`,`component`,`remark`,`is_deleted`) VALUES
|
||||
(2090000000000001040,2090000000000001000,'formal_settlement','正式结算单','formal_settlement','/settlement/formal-settlement','iconfont icon-caidanguanli',4,1,0,1,NULL,'',0),
|
||||
(2090000000000001041,2090000000000001040,'formal_settlement_view','查看','formal_settlement_view','','',1,2,0,1,NULL,'',0),
|
||||
(2090000000000001042,2090000000000001040,'formal_settlement_add','新增','formal_settlement_add','','',2,2,0,1,NULL,'',0),
|
||||
(2090000000000001043,2090000000000001040,'formal_settlement_edit','编辑','formal_settlement_edit','','',3,2,0,1,NULL,'',0),
|
||||
(2090000000000001044,2090000000000001040,'formal_settlement_delete','删除','formal_settlement_delete','','',4,2,0,1,NULL,'',0),
|
||||
(2090000000000001045,2090000000000001040,'formal_settlement_submit','提交审批','formal_settlement_submit','','',5,2,0,1,NULL,'',0),
|
||||
(2090000000000001046,2090000000000001040,'formal_settlement_approve','审批','formal_settlement_approve','','',6,2,0,1,NULL,'',0),
|
||||
(2090000000000001047,2090000000000001040,'formal_settlement_sync','同步金蝶','formal_settlement_sync','','',7,2,0,1,NULL,'',0),
|
||||
(2090000000000001048,2090000000000001040,'formal_settlement_print','打印','formal_settlement_print','','',8,2,0,1,NULL,'',0),
|
||||
(2090000000000001049,2090000000000001040,'formal_settlement_export','导出','formal_settlement_export','','',9,2,0,1,NULL,'',0),
|
||||
(2090000000000001050,2090000000000001040,'formal_settlement_void','作废','formal_settlement_void','','',10,2,0,1,NULL,'',0),
|
||||
(2090000000000001051,2090000000000001040,'formal_settlement_adjust','明细调整','formal_settlement_adjust','','',11,2,0,1,NULL,'',0),
|
||||
(2090000000000001052,2090000000000001040,'formal_settlement_payment','付款申请','formal_settlement_payment','','',12,2,0,1,NULL,'',0)
|
||||
ON DUPLICATE KEY UPDATE `name`=VALUES(`name`),`path`=VALUES(`path`),`is_deleted`=0;
|
||||
@@ -0,0 +1,214 @@
|
||||
-- 结算管理 / 预结算
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `blade_pre_settlement` (
|
||||
`id` bigint(20) NOT NULL COMMENT '主键',
|
||||
`tenant_id` varchar(12) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '000000' COMMENT '租户ID',
|
||||
`create_user` bigint(20) DEFAULT NULL COMMENT '创建人',
|
||||
`create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_user` bigint(20) DEFAULT NULL COMMENT '修改人',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '修改时间',
|
||||
`status` int(11) DEFAULT '1' COMMENT '状态',
|
||||
`is_deleted` int(11) DEFAULT '0' COMMENT '是否已删除',
|
||||
`pre_settlement_no` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '预结算单号',
|
||||
`source_type` varchar(30) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '应收应付' COMMENT '来源',
|
||||
`settlement_type` varchar(30) COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'payable' COMMENT '结算类型',
|
||||
`project_id` bigint(20) DEFAULT NULL COMMENT '项目ID',
|
||||
`project_name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '项目名称',
|
||||
`dept_id` bigint(20) DEFAULT NULL COMMENT '所属组织ID',
|
||||
`dept_name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '所属组织',
|
||||
`contract_id` bigint(20) NOT NULL COMMENT '合同ID',
|
||||
`contract_no` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '合同编号',
|
||||
`contract_name` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '合同名称',
|
||||
`payer_name` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '付款方',
|
||||
`payee_name` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '收款方',
|
||||
`currency` varchar(20) COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'RMB' COMMENT '结算币种',
|
||||
`settlement_amount` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '结算金额',
|
||||
`local_currency` varchar(20) COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'RMB' COMMENT '本位币',
|
||||
`local_settlement_amount` decimal(18,2) DEFAULT NULL COMMENT '本位币合计',
|
||||
`exchange_rate_date` date DEFAULT NULL COMMENT '汇率日期',
|
||||
`exchange_rate` decimal(18,6) DEFAULT NULL COMMENT '结算汇率',
|
||||
`approval_status` varchar(30) COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'draft' COMMENT '审核状态',
|
||||
`current_node` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '当前节点',
|
||||
`current_processor` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '当前处理人',
|
||||
`advance_no` varchar(500) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '预付单号',
|
||||
`advance_applied_amount` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '申请预付金额',
|
||||
`advance_paid_amount` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '已付款金额',
|
||||
`formal_settlement_no` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '正式结算单号',
|
||||
`attachments_json` longtext COLLATE utf8mb4_general_ci COMMENT '附件JSON',
|
||||
`remark` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
|
||||
`approved_time` datetime DEFAULT NULL COMMENT '审核通过时间',
|
||||
`formal_settled_time` datetime DEFAULT NULL COMMENT '正式结算时间',
|
||||
`void_reason` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '作废原因',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE KEY `uk_pre_settlement_no` (`tenant_id`,`pre_settlement_no`) USING BTREE,
|
||||
KEY `idx_pre_settlement_contract` (`contract_id`) USING BTREE,
|
||||
KEY `idx_pre_settlement_project` (`project_id`) USING BTREE,
|
||||
KEY `idx_pre_settlement_approval` (`approval_status`) USING BTREE,
|
||||
KEY `idx_pre_settlement_create_time` (`create_time`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='预结算单';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `blade_pre_settlement_detail` (
|
||||
`id` bigint(20) NOT NULL COMMENT '主键',
|
||||
`tenant_id` varchar(12) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '000000' COMMENT '租户ID',
|
||||
`create_user` bigint(20) DEFAULT NULL COMMENT '创建人',
|
||||
`create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_user` bigint(20) DEFAULT NULL COMMENT '修改人',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '修改时间',
|
||||
`status` int(11) DEFAULT '1' COMMENT '状态',
|
||||
`is_deleted` int(11) DEFAULT '0' COMMENT '是否已删除',
|
||||
`pre_settlement_id` bigint(20) NOT NULL COMMENT '预结算单ID',
|
||||
`source_detail_id` bigint(20) NOT NULL COMMENT '应收应付明细ID',
|
||||
`line_no` int(11) NOT NULL COMMENT '行号',
|
||||
`document_no` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '单据号',
|
||||
`waybill_id` bigint(20) DEFAULT NULL COMMENT '运单ID',
|
||||
`waybill_no` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '运单号',
|
||||
`vehicle_no` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '车号',
|
||||
`departure_address` varchar(500) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '发货地址',
|
||||
`arrival_address` varchar(500) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '到货地址',
|
||||
`actual_departure_time` datetime DEFAULT NULL COMMENT '实际发货时间',
|
||||
`actual_completion_time` datetime DEFAULT NULL COMMENT '实际完成时间',
|
||||
`transport_type` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '运输类型',
|
||||
`cargo_name` varchar(500) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '货物名称',
|
||||
`cargo_type` varchar(500) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '货物类型',
|
||||
`transport_quantity` decimal(18,6) DEFAULT NULL COMMENT '运输总量',
|
||||
`quantity_unit` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '数量单位',
|
||||
`mileage` decimal(18,2) DEFAULT NULL COMMENT '里程',
|
||||
`batch_no` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '批次号',
|
||||
`unit_price` decimal(18,2) DEFAULT NULL COMMENT '运输单价',
|
||||
`freight_amount` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '运费',
|
||||
`fee_items_json` longtext COLLATE utf8mb4_general_ci COMMENT '费用项JSON',
|
||||
`original_amount` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '原金额',
|
||||
`adjust_amount` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '调整金额',
|
||||
`settlement_amount_tax` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '结算金额(含税)',
|
||||
`settlement_amount_no_tax` decimal(18,2) DEFAULT NULL COMMENT '结算金额(不含税)',
|
||||
`currency` varchar(20) COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'RMB' COMMENT '币种',
|
||||
`remark` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
KEY `idx_pre_settlement_source_detail` (`source_detail_id`) USING BTREE,
|
||||
KEY `idx_pre_settlement_detail_bill` (`pre_settlement_id`) USING BTREE,
|
||||
KEY `idx_pre_settlement_detail_waybill` (`waybill_id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='预结算明细';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `blade_pre_settlement_detail_fee` (
|
||||
`id` bigint(20) NOT NULL COMMENT '主键',
|
||||
`tenant_id` varchar(12) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '000000' COMMENT '租户ID',
|
||||
`create_user` bigint(20) DEFAULT NULL COMMENT '创建人',
|
||||
`create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_user` bigint(20) DEFAULT NULL COMMENT '修改人',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '修改时间',
|
||||
`status` int(11) DEFAULT '1' COMMENT '状态',
|
||||
`is_deleted` int(11) DEFAULT '0' COMMENT '是否已删除',
|
||||
`pre_settlement_detail_id` bigint(20) NOT NULL COMMENT '预结算明细ID',
|
||||
`source_fee_id` bigint(20) DEFAULT NULL COMMENT '源费用行ID',
|
||||
`line_no` varchar(30) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '行号',
|
||||
`cargo_name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '货物名称',
|
||||
`cargo_type` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '货物类型',
|
||||
`transport_quantity` decimal(18,6) DEFAULT NULL COMMENT '运输量',
|
||||
`quantity_unit` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '数量单位',
|
||||
`mileage` decimal(18,2) DEFAULT NULL COMMENT '里程',
|
||||
`unit_price` decimal(18,2) DEFAULT NULL COMMENT '运输单价',
|
||||
`freight_amount` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '运费',
|
||||
`fee_items_json` longtext COLLATE utf8mb4_general_ci COMMENT '费用项JSON',
|
||||
`original_amount` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '原金额',
|
||||
`adjust_amount` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '调整金额',
|
||||
`settlement_amount_tax` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '结算金额(含税)',
|
||||
`settlement_amount_no_tax` decimal(18,2) DEFAULT NULL COMMENT '结算金额(不含税)',
|
||||
`remark` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
KEY `idx_pre_settlement_detail_fee_detail` (`pre_settlement_detail_id`) USING BTREE,
|
||||
KEY `idx_pre_settlement_detail_fee_source` (`source_fee_id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='预结算明细费用快照';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `blade_pre_settlement_summary_fee` (
|
||||
`id` bigint(20) NOT NULL COMMENT '主键',
|
||||
`tenant_id` varchar(12) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '000000' COMMENT '租户ID',
|
||||
`create_user` bigint(20) DEFAULT NULL COMMENT '创建人',
|
||||
`create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_user` bigint(20) DEFAULT NULL COMMENT '修改人',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '修改时间',
|
||||
`status` int(11) DEFAULT '1' COMMENT '状态',
|
||||
`is_deleted` int(11) DEFAULT '0' COMMENT '是否已删除',
|
||||
`pre_settlement_id` bigint(20) NOT NULL COMMENT '预结算单ID',
|
||||
`line_no` int(11) NOT NULL COMMENT '行号',
|
||||
`fee_type` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '费用类型',
|
||||
`fee_item` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '费用项',
|
||||
`original_amount` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '原金额',
|
||||
`adjust_amount` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '调整金额',
|
||||
`settlement_amount` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '结算金额',
|
||||
`remark` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
|
||||
`manual_flag` int(11) NOT NULL DEFAULT '0' COMMENT '是否手工添加',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
KEY `idx_pre_settlement_summary_bill` (`pre_settlement_id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='预结算合计费用';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `blade_pre_settlement_advance` (
|
||||
`id` bigint(20) NOT NULL COMMENT '主键',
|
||||
`tenant_id` varchar(12) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '000000' COMMENT '租户ID',
|
||||
`create_user` bigint(20) DEFAULT NULL COMMENT '创建人',
|
||||
`create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_user` bigint(20) DEFAULT NULL COMMENT '修改人',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '修改时间',
|
||||
`status` int(11) DEFAULT '1' COMMENT '状态',
|
||||
`is_deleted` int(11) DEFAULT '0' COMMENT '是否已删除',
|
||||
`pre_settlement_id` bigint(20) NOT NULL COMMENT '预结算单ID',
|
||||
`advance_no` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '预付单号',
|
||||
`applied_amount` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '申请预付金额',
|
||||
`paid_amount` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '已付款金额',
|
||||
`bill_status` varchar(30) COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'reviewing' COMMENT '单据状态',
|
||||
`kingdee_advance_no` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '金蝶预付单号',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE KEY `uk_pre_settlement_advance_no` (`tenant_id`,`advance_no`) USING BTREE,
|
||||
KEY `idx_pre_settlement_advance_bill` (`pre_settlement_id`) USING BTREE,
|
||||
KEY `idx_pre_settlement_advance_status` (`bill_status`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='预结算预付记录';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `blade_pre_settlement_change_record` (
|
||||
`id` bigint(20) NOT NULL COMMENT '主键',
|
||||
`tenant_id` varchar(12) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '000000' COMMENT '租户ID',
|
||||
`create_user` bigint(20) DEFAULT NULL COMMENT '创建人',
|
||||
`create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_user` bigint(20) DEFAULT NULL COMMENT '修改人',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '修改时间',
|
||||
`status` int(11) DEFAULT '1' COMMENT '状态',
|
||||
`is_deleted` int(11) DEFAULT '0' COMMENT '是否已删除',
|
||||
`pre_settlement_id` bigint(20) NOT NULL COMMENT '预结算单ID',
|
||||
`change_type` varchar(50) COLLATE utf8mb4_general_ci NOT NULL COMMENT '变更类型',
|
||||
`line_no` int(11) DEFAULT NULL COMMENT '行号',
|
||||
`operation_type` varchar(30) COLLATE utf8mb4_general_ci NOT NULL COMMENT '操作类型',
|
||||
`change_content` text COLLATE utf8mb4_general_ci NOT NULL COMMENT '变更内容',
|
||||
`operator_name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '操作人',
|
||||
`change_reason` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '变更原因',
|
||||
`change_time` datetime NOT NULL COMMENT '变更时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
KEY `idx_pre_settlement_change_bill` (`pre_settlement_id`) USING BTREE,
|
||||
KEY `idx_pre_settlement_change_time` (`change_time`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='预结算变更记录';
|
||||
|
||||
-- 结算管理菜单下新增预结算及按钮权限。
|
||||
INSERT INTO `blade_menu`
|
||||
(`id`, `parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `component`, `remark`, `is_deleted`)
|
||||
VALUES
|
||||
(2090000000000001020, 2090000000000001000, 'pre_settlement', '预结算', 'pre_settlement', '/settlement/pre-settlement', 'iconfont icon-caidanguanli', 3, 1, 0, 1, NULL, '', 0),
|
||||
(2090000000000001021, 2090000000000001020, 'pre_settlement_view', '查看', 'pre_settlement_view', '', '', 1, 2, 0, 1, NULL, '', 0),
|
||||
(2090000000000001022, 2090000000000001020, 'pre_settlement_add', '新增', 'pre_settlement_add', '', '', 2, 2, 0, 1, NULL, '', 0),
|
||||
(2090000000000001023, 2090000000000001020, 'pre_settlement_edit', '编辑', 'pre_settlement_edit', '', '', 3, 2, 0, 1, NULL, '', 0),
|
||||
(2090000000000001024, 2090000000000001020, 'pre_settlement_delete', '删除', 'pre_settlement_delete', '', '', 4, 2, 0, 1, NULL, '', 0),
|
||||
(2090000000000001025, 2090000000000001020, 'pre_settlement_submit', '提交审批', 'pre_settlement_submit', '', '', 5, 2, 0, 1, NULL, '', 0),
|
||||
(2090000000000001026, 2090000000000001020, 'pre_settlement_approve', '审批', 'pre_settlement_approve', '', '', 6, 2, 0, 1, NULL, '', 0),
|
||||
(2090000000000001027, 2090000000000001020, 'pre_settlement_advance', '预付申请', 'pre_settlement_advance', '', '', 7, 2, 0, 1, NULL, '', 0),
|
||||
(2090000000000001028, 2090000000000001020, 'pre_settlement_formal', '尾款结算', 'pre_settlement_formal', '', '', 8, 2, 0, 1, NULL, '', 0),
|
||||
(2090000000000001029, 2090000000000001020, 'pre_settlement_print', '打印结算单', 'pre_settlement_print', '', '', 9, 2, 0, 1, NULL, '', 0),
|
||||
(2090000000000001030, 2090000000000001020, 'pre_settlement_export', '导出', 'pre_settlement_export', '', '', 10, 2, 0, 1, NULL, '', 0),
|
||||
(2090000000000001031, 2090000000000001020, 'pre_settlement_adjust', '明细调整', 'pre_settlement_adjust', '', '', 11, 2, 0, 1, NULL, '', 0),
|
||||
(2090000000000001032, 2090000000000001020, 'pre_settlement_void', '作废', 'pre_settlement_void', '', '', 12, 2, 0, 1, NULL, '', 0)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
`name` = VALUES(`name`),
|
||||
`path` = VALUES(`path`),
|
||||
`sort` = VALUES(`sort`),
|
||||
`is_deleted` = 0;
|
||||
Reference in New Issue
Block a user