1、新增预结算单
2、新增正式结算单 3、调整IAM认证登录
This commit is contained in:
+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;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user