From 3e265fc71ee33df2dc9984d90a6e80731be69fbf Mon Sep 17 00:00:00 2001 From: b2894lxlx <517289602@qq.com> Date: Sat, 22 Aug 2026 17:25:26 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=94=B6=E4=BB=98=E6=AC=BE?= =?UTF-8?q?=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pojo/dto/BillLedgerSaveRequest.java | 34 + .../pojo/dto/BillPaymentSaveRequest.java | 45 ++ .../pojo/dto/BillPaymentStatusRequest.java | 39 + .../dto/InvoiceApplicationSaveRequest.java | 82 +++ .../dto/InvoiceApplicationStatusRequest.java | 43 ++ .../pojo/dto/InvoiceReceiptSaveRequest.java | 61 ++ .../pojo/dto/InvoiceReceiptStatusRequest.java | 43 ++ .../dto/PaymentApplicationInvoiceRequest.java | 41 ++ .../dto/PaymentApplicationSaveRequest.java | 61 ++ .../dto/PaymentApplicationStatusRequest.java | 33 + .../dto/ReceiptClaimAttachmentsRequest.java | 48 ++ .../pojo/dto/ReceiptClaimRequest.java | 63 ++ .../pojo/dto/ReceiptFlowSyncRequest.java | 69 ++ .../transport/pojo/entity/BillLedger.java | 42 ++ .../pojo/entity/BillLedgerUsage.java | 29 + .../transport/pojo/entity/BillPayment.java | 57 ++ .../pojo/entity/InvoiceApplication.java | 83 +++ .../pojo/entity/InvoiceApplicationDetail.java | 68 ++ .../pojo/entity/InvoiceApplicationLine.java | 58 ++ .../pojo/entity/InvoiceApplicationRecord.java | 53 ++ .../entity/InvoiceApplicationSettlement.java | 52 ++ .../pojo/entity/InvoiceApplicationSheet.java | 49 ++ .../transport/pojo/entity/InvoiceReceipt.java | 83 +++ .../pojo/entity/InvoiceReceiptRecord.java | 58 ++ .../pojo/entity/InvoiceReceiptSettlement.java | 58 ++ .../pojo/entity/KingdeeInvoicePool.java | 68 ++ .../pojo/entity/KingdeeReceiptFlow.java | 64 ++ .../pojo/entity/PaymentApplication.java | 76 ++ .../entity/PaymentApplicationInvoice.java | 47 ++ .../pojo/entity/PaymentApplicationRecord.java | 43 ++ .../transport/pojo/entity/ReceiptClaim.java | 74 ++ .../pojo/entity/ReceiptClaimSettlement.java | 63 ++ .../pojo/entity/ReceiptFlowRecord.java | 64 ++ .../transport/pojo/vo/BillLedgerVO.java | 31 + .../transport/pojo/vo/BillPaymentVO.java | 46 ++ .../pojo/vo/InvoiceApplicationSheetVO.java | 47 ++ .../pojo/vo/InvoiceApplicationVO.java | 56 ++ .../transport/pojo/vo/InvoiceReceiptVO.java | 56 ++ .../pojo/vo/PaymentApplicationVO.java | 47 ++ .../pojo/vo/ReceiptClaimRecordVO.java | 93 +++ .../transport/pojo/vo/ReceiptFlowVO.java | 73 ++ .../controller/BillLedgerController.java | 82 +++ .../controller/BillPaymentController.java | 118 +++ .../InvoiceApplicationController.java | 154 ++++ .../controller/InvoiceReceiptController.java | 157 ++++ .../PaymentApplicationController.java | 87 +++ .../ReceiptClaimRecordController.java | 90 +++ .../controller/ReceiptFlowController.java | 102 +++ .../transport/mapper/BillLedgerMapper.java | 14 + .../mapper/BillLedgerUsageMapper.java | 14 + .../transport/mapper/BillPaymentMapper.java | 35 + .../InvoiceApplicationDetailMapper.java | 39 + .../mapper/InvoiceApplicationLineMapper.java | 39 + .../mapper/InvoiceApplicationMapper.java | 39 + .../InvoiceApplicationRecordMapper.java | 39 + .../InvoiceApplicationSettlementMapper.java | 39 + .../mapper/InvoiceApplicationSheetMapper.java | 39 + .../mapper/InvoiceReceiptMapper.java | 39 + .../mapper/InvoiceReceiptRecordMapper.java | 39 + .../InvoiceReceiptSettlementMapper.java | 39 + .../mapper/KingdeeInvoicePoolMapper.java | 39 + .../mapper/KingdeeReceiptFlowMapper.java | 39 + .../PaymentApplicationInvoiceMapper.java | 29 + .../mapper/PaymentApplicationMapper.java | 29 + .../PaymentApplicationRecordMapper.java | 29 + .../transport/mapper/ReceiptClaimMapper.java | 50 ++ .../transport/mapper/ReceiptClaimMapper.xml | 114 +++ .../mapper/ReceiptClaimSettlementMapper.java | 39 + .../mapper/ReceiptFlowRecordMapper.java | 39 + .../transport/service/IBillLedgerService.java | 24 + .../service/IBillPaymentService.java | 45 ++ .../service/IInvoiceApplicationService.java | 57 ++ .../service/IInvoiceReceiptService.java | 69 ++ .../service/IPaymentApplicationService.java | 40 + .../service/IReceiptClaimRecordService.java | 49 ++ .../service/IReceiptFlowService.java | 54 ++ .../service/impl/BillLedgerServiceImpl.java | 302 ++++++++ .../service/impl/BillPaymentServiceImpl.java | 343 +++++++++ .../impl/InvoiceApplicationServiceImpl.java | 643 ++++++++++++++++ .../impl/InvoiceReceiptServiceImpl.java | 684 ++++++++++++++++++ .../impl/PaymentApplicationServiceImpl.java | 392 ++++++++++ .../impl/ReceiptClaimRecordServiceImpl.java | 259 +++++++ .../service/impl/ReceiptFlowServiceImpl.java | 504 +++++++++++++ .../transport/wrapper/BillLedgerWrapper.java | 44 ++ .../transport/wrapper/BillPaymentWrapper.java | 57 ++ .../wrapper/InvoiceApplicationWrapper.java | 66 ++ .../wrapper/InvoiceReceiptWrapper.java | 67 ++ .../wrapper/PaymentApplicationWrapper.java | 59 ++ .../transport/wrapper/ReceiptFlowWrapper.java | 67 ++ .../transport/blade_bill_ledger_20260821.sql | 113 +++ .../transport/blade_bill_payment_20260822.sql | 79 ++ .../blade_invoice_application_20260821.sql | 187 +++++ .../blade_invoice_receipt_20260821.sql | 145 ++++ .../blade_payment_application_20260821.sql | 46 ++ .../transport/blade_receipt_flow_20260821.sql | 114 +++ ...ade_receipt_flow_claim_record_20260821.sql | 107 +++ 96 files changed, 8527 insertions(+) create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/BillLedgerSaveRequest.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/BillPaymentSaveRequest.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/BillPaymentStatusRequest.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceApplicationSaveRequest.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceApplicationStatusRequest.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceReceiptSaveRequest.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceReceiptStatusRequest.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/PaymentApplicationInvoiceRequest.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/PaymentApplicationSaveRequest.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/PaymentApplicationStatusRequest.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/ReceiptClaimAttachmentsRequest.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/ReceiptClaimRequest.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/ReceiptFlowSyncRequest.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/BillLedger.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/BillLedgerUsage.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/BillPayment.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplication.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationDetail.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationLine.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationRecord.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationSettlement.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationSheet.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceReceipt.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceReceiptRecord.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceReceiptSettlement.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/KingdeeInvoicePool.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/KingdeeReceiptFlow.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/PaymentApplication.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/PaymentApplicationInvoice.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/PaymentApplicationRecord.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/ReceiptClaim.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/ReceiptClaimSettlement.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/ReceiptFlowRecord.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/BillLedgerVO.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/BillPaymentVO.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/InvoiceApplicationSheetVO.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/InvoiceApplicationVO.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/InvoiceReceiptVO.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/PaymentApplicationVO.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/ReceiptClaimRecordVO.java create mode 100644 blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/ReceiptFlowVO.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/controller/BillLedgerController.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/controller/BillPaymentController.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/controller/InvoiceApplicationController.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/controller/InvoiceReceiptController.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/controller/PaymentApplicationController.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/controller/ReceiptClaimRecordController.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/controller/ReceiptFlowController.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/BillLedgerMapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/BillLedgerUsageMapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/BillPaymentMapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationDetailMapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationLineMapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationMapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationRecordMapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationSettlementMapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationSheetMapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceReceiptMapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceReceiptRecordMapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceReceiptSettlementMapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/KingdeeInvoicePoolMapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/KingdeeReceiptFlowMapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/PaymentApplicationInvoiceMapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/PaymentApplicationMapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/PaymentApplicationRecordMapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/ReceiptClaimMapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/ReceiptClaimMapper.xml create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/ReceiptClaimSettlementMapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/ReceiptFlowRecordMapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/service/IBillLedgerService.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/service/IBillPaymentService.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/service/IInvoiceApplicationService.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/service/IInvoiceReceiptService.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/service/IPaymentApplicationService.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/service/IReceiptClaimRecordService.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/service/IReceiptFlowService.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/BillLedgerServiceImpl.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/BillPaymentServiceImpl.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/InvoiceApplicationServiceImpl.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/InvoiceReceiptServiceImpl.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/PaymentApplicationServiceImpl.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ReceiptClaimRecordServiceImpl.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ReceiptFlowServiceImpl.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/BillLedgerWrapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/BillPaymentWrapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/InvoiceApplicationWrapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/InvoiceReceiptWrapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/PaymentApplicationWrapper.java create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/ReceiptFlowWrapper.java create mode 100644 doc/sql/transport/blade_bill_ledger_20260821.sql create mode 100644 doc/sql/transport/blade_bill_payment_20260822.sql create mode 100644 doc/sql/transport/blade_invoice_application_20260821.sql create mode 100644 doc/sql/transport/blade_invoice_receipt_20260821.sql create mode 100644 doc/sql/transport/blade_payment_application_20260821.sql create mode 100644 doc/sql/transport/blade_receipt_flow_20260821.sql create mode 100644 doc/sql/transport/blade_receipt_flow_claim_record_20260821.sql diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/BillLedgerSaveRequest.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/BillLedgerSaveRequest.java new file mode 100644 index 0000000..bc68385 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/BillLedgerSaveRequest.java @@ -0,0 +1,34 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + */ +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; + +/** 汇票台账保存请求。 @author Chill */ +@Data +public class BillLedgerSaveRequest implements Serializable { + @Serial private static final long serialVersionUID = 1L; + private Long id; + private String billNo; + private Long issuerId; + private String receiverName; + private String billType; + private BigDecimal faceAmount; + private LocalDate issueDate; + private LocalDate maturityDate; + private String availableDeptIdsJson; + private String availableDeptNames; + private Long feeBearerId; + private BigDecimal confirmedDiscountRate; + private String issuingBank; + private BigDecimal bankDiscountReferenceRate; + private String attachmentsJson; + private String remark; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/BillPaymentSaveRequest.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/BillPaymentSaveRequest.java new file mode 100644 index 0000000..08b5724 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/BillPaymentSaveRequest.java @@ -0,0 +1,45 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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; + +/** 汇票付款保存请求。 @author Chill */ +@Data +public class BillPaymentSaveRequest implements Serializable { + @Serial private static final long serialVersionUID = 1L; + private Long id; + private Long billLedgerId; + private BigDecimal usedAmount; + private LocalDate paymentDate; + private String attachmentsJson; + private String remark; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/BillPaymentStatusRequest.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/BillPaymentStatusRequest.java new file mode 100644 index 0000000..4ce0b87 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/BillPaymentStatusRequest.java @@ -0,0 +1,39 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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 BillPaymentStatusRequest implements Serializable { + @Serial private static final long serialVersionUID = 1L; + private Long id; + private String reason; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceApplicationSaveRequest.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceApplicationSaveRequest.java new file mode 100644 index 0000000..b6b5274 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceApplicationSaveRequest.java @@ -0,0 +1,82 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.util.List; + +/** + * 开票申请保存请求 + * + * @author Chill + */ +@Data +public class InvoiceApplicationSaveRequest implements Serializable { + @Serial private static final long serialVersionUID = 1L; + private Long id; + private String invoiceType; + private String departmentEmails; + private Long receiverInvoiceInfoId; + private String contactName; + private String contactPhone; + private String email; + private String attachmentsJson; + private String remark; + private List settlements; + private List detailIds; + private List sheets; + + @Data + public static class SettlementRow implements Serializable { + @Serial private static final long serialVersionUID = 1L; + private Long settlementId; + private BigDecimal allocatedInvoiceAmount; + } + + @Data + public static class SheetRow implements Serializable { + @Serial private static final long serialVersionUID = 1L; + private List lines; + } + + @Data + public static class LineRow implements Serializable { + @Serial private static final long serialVersionUID = 1L; + private String goodsCategory; + private String goodsName; + private String unit; + private BigDecimal quantity; + private BigDecimal unitPriceNoTax; + private BigDecimal amountWithTax; + private BigDecimal taxRate; + private BigDecimal taxAmount; + private String remark; + } +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceApplicationStatusRequest.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceApplicationStatusRequest.java new file mode 100644 index 0000000..fa84d30 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceApplicationStatusRequest.java @@ -0,0 +1,43 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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 InvoiceApplicationStatusRequest implements Serializable { + @Serial private static final long serialVersionUID = 1L; + private Long id; + private String reason; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceReceiptSaveRequest.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceReceiptSaveRequest.java new file mode 100644 index 0000000..e50ef5b --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceReceiptSaveRequest.java @@ -0,0 +1,61 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.util.List; + +/** + * 收票登记保存请求 + * + * @author Chill + */ +@Data +public class InvoiceReceiptSaveRequest implements Serializable { + @Serial private static final long serialVersionUID = 1L; + private Long id; + private Long kingdeeInvoicePoolId; + private String phone; + private String customerEmails; + private String departmentEmails; + private String attachmentsJson; + private String remark; + private List settlements; + + /** + * 结算单分摊行 + */ + @Data + public static class SettlementRow implements Serializable { + @Serial private static final long serialVersionUID = 1L; + private Long settlementId; + private BigDecimal allocatedInvoiceAmount; + } +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceReceiptStatusRequest.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceReceiptStatusRequest.java new file mode 100644 index 0000000..52cdc00 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceReceiptStatusRequest.java @@ -0,0 +1,43 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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 InvoiceReceiptStatusRequest implements Serializable { + @Serial private static final long serialVersionUID = 1L; + private Long id; + private String reason; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/PaymentApplicationInvoiceRequest.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/PaymentApplicationInvoiceRequest.java new file mode 100644 index 0000000..3e6d8bb --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/PaymentApplicationInvoiceRequest.java @@ -0,0 +1,41 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments from this software for such purposes. + * Copyright of this software remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is not liable for any claims arising from secondary or illegal development. + *

+ * 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; + +/** 付款申请发票请求。 @author Chill */ +@Data +public class PaymentApplicationInvoiceRequest implements Serializable { + @Serial private static final long serialVersionUID = 1L; + private String settlementNo; + private String invoiceNo; + private LocalDate invoiceDate; + private String invoiceType; + private BigDecimal taxRate; + private BigDecimal invoiceAmount; + private BigDecimal matchedAmount; + private String attachmentJson; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/PaymentApplicationSaveRequest.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/PaymentApplicationSaveRequest.java new file mode 100644 index 0000000..498de38 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/PaymentApplicationSaveRequest.java @@ -0,0 +1,61 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments from this software for such purposes. + * Copyright of this software remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is not liable for any claims arising from secondary or illegal development. + *

+ * 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.util.List; + +/** 付款申请保存请求。 @author Chill */ +@Data +public class PaymentApplicationSaveRequest implements Serializable { + @Serial private static final long serialVersionUID = 1L; + private Long id; + private String paymentType; + private Long settlementId; + private Long preSettlementId; + 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 BigDecimal settlementAmount; + private BigDecimal payableAmount; + private String billType; + private BigDecimal paymentRatio; + private BigDecimal appliedAmount; + private String paymentMethod; + private Long billLedgerId; + private String billNo; + private Long receiptAccountId; + private String receiptAccountName; + private String bankName; + private String bankAccount; + private String attachmentsJson; + private String remark; + private List invoices; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/PaymentApplicationStatusRequest.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/PaymentApplicationStatusRequest.java new file mode 100644 index 0000000..e351f75 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/PaymentApplicationStatusRequest.java @@ -0,0 +1,33 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments from this software for such purposes. + * Copyright of this software remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is not liable for any claims arising from secondary or illegal development. + *

+ * 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 PaymentApplicationStatusRequest implements Serializable { + @Serial private static final long serialVersionUID = 1L; + private Long id; + private String reason; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/ReceiptClaimAttachmentsRequest.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/ReceiptClaimAttachmentsRequest.java new file mode 100644 index 0000000..6bcb5dc --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/ReceiptClaimAttachmentsRequest.java @@ -0,0 +1,48 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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 ReceiptClaimAttachmentsRequest implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + private Long id; + private String attachmentsJson; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/ReceiptClaimRequest.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/ReceiptClaimRequest.java new file mode 100644 index 0000000..2039c76 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/ReceiptClaimRequest.java @@ -0,0 +1,63 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.util.List; + +/** + * 收款流水认领请求 + * + * @author Chill + */ +@Data +public class ReceiptClaimRequest implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + private Long flowId; + private String attachmentsJson; + private String remark; + private List settlements; + + /** + * 结算单分摊行 + */ + @Data + public static class SettlementRow implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + private Long settlementId; + private BigDecimal allocatedReceiptAmount; + } +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/ReceiptFlowSyncRequest.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/ReceiptFlowSyncRequest.java new file mode 100644 index 0000000..fa443a7 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/ReceiptFlowSyncRequest.java @@ -0,0 +1,69 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.LocalDateTime; +import java.util.List; + +/** + * 金蝶收款流水同步请求 + * + * @author Chill + */ +@Data +public class ReceiptFlowSyncRequest implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + private List flows; + + /** + * 金蝶收款流水行 + */ + @Data + public static class FlowRow implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + private String receiptNoticeNo; + private String payerName; + private BigDecimal receiptAmount; + private String counterpartyName; + private String counterpartyAccount; + private String counterpartyBank; + private String summary; + private LocalDateTime transactionTime; + private String detailSerialNo; + private LocalDateTime sourceUpdatedTime; + } +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/BillLedger.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/BillLedger.java new file mode 100644 index 0000000..bb95358 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/BillLedger.java @@ -0,0 +1,42 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + */ +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.LocalDate; + +/** 汇票台账实体。 @author Chill */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("blade_bill_ledger") +public class BillLedger extends TenantEntity { + @Serial private static final long serialVersionUID = 1L; + private String billNo; + private Long issuerId; + private String issuerName; + private Long receiverId; + private String receiverName; + private String billType; + private BigDecimal faceAmount; + private BigDecimal availableBalance; + private LocalDate issueDate; + private LocalDate maturityDate; + private String availableDeptIdsJson; + private String availableDeptNames; + private Long feeBearerId; + private String feeBearerName; + private BigDecimal confirmedDiscountRate; + private String issuingBank; + private BigDecimal bankDiscountReferenceRate; + private BigDecimal estimatedDiscountFee; + private String attachmentsJson; + private String remark; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/BillLedgerUsage.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/BillLedgerUsage.java new file mode 100644 index 0000000..b52c0a8 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/BillLedgerUsage.java @@ -0,0 +1,29 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + */ +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_bill_ledger_usage") +public class BillLedgerUsage extends TenantEntity { + @Serial private static final long serialVersionUID = 1L; + private Long billLedgerId; + private Long paymentApplicationId; + private Long billPaymentId; + private String applicationNo; + private BigDecimal usedAmount; + private Long useDeptId; + private String useDeptName; + private String usageStatus; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/BillPayment.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/BillPayment.java new file mode 100644 index 0000000..cf15e7f --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/BillPayment.java @@ -0,0 +1,57 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.LocalDate; + +/** 汇票付款实体。 @author Chill */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("blade_bill_payment") +public class BillPayment extends TenantEntity { + @Serial private static final long serialVersionUID = 1L; + private String paymentNo; + private Long billLedgerId; + private String billNo; + private BigDecimal faceAmount; + private BigDecimal availableBalance; + private BigDecimal usedAmount; + private Long deptId; + private String deptName; + private LocalDate paymentDate; + private String approvalStatus; + private String currentNode; + private String currentProcessor; + private String attachmentsJson; + private String remark; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplication.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplication.java new file mode 100644 index 0000000..bf03a3c --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplication.java @@ -0,0 +1,83 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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_invoice_application") +@Schema(description = "开票申请") +public class InvoiceApplication extends TenantEntity { + @Serial private static final long serialVersionUID = 1L; + private String applicationNo; + private Long projectId; + private String projectName; + private Long deptId; + private String deptName; + private String issuerName; + private Long receiverCustomerId; + private String receiverName; + private String invoiceType; + private BigDecimal availableInvoiceAmount; + private BigDecimal invoiceAmount; + private LocalDate applicationDate; + private String applicantName; + private Long undertakingDeptId; + private String undertakingDeptName; + private String departmentEmails; + private Long receiverInvoiceInfoId; + private String taxpayerNo; + private String bankName; + private String bankAccount; + private String registeredAddress; + private String contactName; + private String contactPhone; + private String email; + private String approvalStatus; + private String currentNode; + private String currentProcessor; + private String kingdeeBillNo; + private String kingdeeStatus; + private LocalDateTime syncedTime; + private String attachmentsJson; + private String remark; + private String voidReason; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationDetail.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationDetail.java new file mode 100644 index 0000000..4410493 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationDetail.java @@ -0,0 +1,68 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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_invoice_application_detail") +public class InvoiceApplicationDetail extends TenantEntity { + @Serial private static final long serialVersionUID = 1L; + private Long invoiceApplicationId; + private Long formalSettlementId; + private Long formalSettlementDetailId; + private Integer lineNo; + private String documentNo; + 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 freightAmount; + private String feeItemsJson; + private BigDecimal settlementAmountTax; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationLine.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationLine.java new file mode 100644 index 0000000..1615453 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationLine.java @@ -0,0 +1,58 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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_invoice_application_line") +public class InvoiceApplicationLine extends TenantEntity { + @Serial private static final long serialVersionUID = 1L; + private Long invoiceApplicationId; + private Long invoiceSheetId; + private Integer lineNo; + private String goodsCategory; + private String goodsName; + private String unit; + private BigDecimal quantity; + private BigDecimal unitPriceNoTax; + private BigDecimal amountWithTax; + private BigDecimal taxRate; + private BigDecimal taxAmount; + private String remark; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationRecord.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationRecord.java new file mode 100644 index 0000000..8a411bd --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationRecord.java @@ -0,0 +1,53 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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; + +/** + * 开票申请操作记录实体类 + * + * @author Chill + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("blade_invoice_application_record") +public class InvoiceApplicationRecord extends TenantEntity { + @Serial private static final long serialVersionUID = 1L; + private Long invoiceApplicationId; + private String actionType; + private String actionName; + private String fromStatus; + private String toStatus; + private String operatorName; + private String reason; + private String kingdeeBillNo; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationSettlement.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationSettlement.java new file mode 100644 index 0000000..57a0339 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationSettlement.java @@ -0,0 +1,52 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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_invoice_application_settlement") +public class InvoiceApplicationSettlement extends TenantEntity { + @Serial private static final long serialVersionUID = 1L; + private Long invoiceApplicationId; + private Long formalSettlementId; + private String formalSettlementNo; + private BigDecimal settlementAmount; + private BigDecimal availableInvoiceAmount; + private BigDecimal allocatedInvoiceAmount; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationSheet.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationSheet.java new file mode 100644 index 0000000..8550946 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationSheet.java @@ -0,0 +1,49 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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_invoice_application_sheet") +public class InvoiceApplicationSheet extends TenantEntity { + @Serial private static final long serialVersionUID = 1L; + private Long invoiceApplicationId; + private Integer sheetNo; + private BigDecimal invoiceAmount; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceReceipt.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceReceipt.java new file mode 100644 index 0000000..67859e1 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceReceipt.java @@ -0,0 +1,83 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * Author: Chill Zhuang (bladejava@qq.com) + */ +package org.springblade.transport.pojo.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +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; + +/** + * 收票登记实体类 + * + * @author Chill + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("blade_invoice_receipt") +@Schema(description = "收票登记") +public class InvoiceReceipt extends TenantEntity { + @Serial private static final long serialVersionUID = 1L; + @JsonSerialize(using = ToStringSerializer.class) + private Long kingdeeInvoicePoolId; + private String invoiceNo; + private LocalDate invoiceDate; + private String invoiceType; + private BigDecimal taxRate; + private BigDecimal invoiceAmount; + private BigDecimal taxAmount; + private String receiverName; + private String issuerName; + @JsonSerialize(using = ToStringSerializer.class) + private Long projectId; + private String projectName; + @JsonSerialize(using = ToStringSerializer.class) + private Long deptId; + private String deptName; + private String payerName; + private String payeeName; + private String bankName; + private String bankAccount; + private String issuingBank; + private String phone; + private String customerEmails; + private String departmentEmails; + private String approvalStatus; + private String currentNode; + private String currentProcessor; + private String kingdeeBillNo; + private String kingdeeStatus; + private String attachmentsJson; + private String remark; + private String voidReason; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceReceiptRecord.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceReceiptRecord.java new file mode 100644 index 0000000..6e50246 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceReceiptRecord.java @@ -0,0 +1,58 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * Author: Chill Zhuang (bladejava@qq.com) + */ +package org.springblade.transport.pojo.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +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; + +/** + * 收票登记操作记录实体类 + * + * @author Chill + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("blade_invoice_receipt_record") +@Schema(description = "收票登记操作记录") +public class InvoiceReceiptRecord extends TenantEntity { + @Serial private static final long serialVersionUID = 1L; + @JsonSerialize(using = ToStringSerializer.class) + private Long invoiceReceiptId; + private String actionType; + private String actionName; + private String fromStatus; + private String toStatus; + private String operatorName; + private String reason; + private String kingdeeBillNo; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceReceiptSettlement.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceReceiptSettlement.java new file mode 100644 index 0000000..4f19d2d --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceReceiptSettlement.java @@ -0,0 +1,58 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * Author: Chill Zhuang (bladejava@qq.com) + */ +package org.springblade.transport.pojo.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +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_invoice_receipt_settlement") +@Schema(description = "收票登记结算单分摊") +public class InvoiceReceiptSettlement extends TenantEntity { + @Serial private static final long serialVersionUID = 1L; + @JsonSerialize(using = ToStringSerializer.class) + private Long invoiceReceiptId; + @JsonSerialize(using = ToStringSerializer.class) + private Long formalSettlementId; + private String formalSettlementNo; + private BigDecimal settlementAmount; + private BigDecimal receivedInvoiceAmount; + private BigDecimal allocatedInvoiceAmount; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/KingdeeInvoicePool.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/KingdeeInvoicePool.java new file mode 100644 index 0000000..261110c --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/KingdeeInvoicePool.java @@ -0,0 +1,68 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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_kingdee_invoice_pool") +@Schema(description = "金蝶进项发票票据池镜像") +public class KingdeeInvoicePool extends TenantEntity { + @Serial private static final long serialVersionUID = 1L; + private String invoiceNo; + private LocalDate invoiceDate; + private String invoiceType; + private BigDecimal taxRate; + private BigDecimal invoiceAmount; + private BigDecimal taxAmount; + private String receiverName; + private String issuerName; + private String bankName; + private String bankAccount; + private String issuingBank; + private String phone; + private String customerEmails; + private String departmentEmails; + private String kingdeeBillNo; + private String kingdeeStatus; + private String attachmentsJson; + private LocalDateTime sourceUpdatedTime; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/KingdeeReceiptFlow.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/KingdeeReceiptFlow.java new file mode 100644 index 0000000..79b75c1 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/KingdeeReceiptFlow.java @@ -0,0 +1,64 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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_kingdee_receipt_flow") +@Schema(description = "金蝶收款流水镜像") +public class KingdeeReceiptFlow extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + private String receiptNoticeNo; + private String payerName; + private BigDecimal receiptAmount; + private String counterpartyName; + private String counterpartyAccount; + private String counterpartyBank; + private String summary; + private LocalDateTime transactionTime; + private String detailSerialNo; + private BigDecimal claimedAmount; + private String claimStatus; + private LocalDateTime sourceUpdatedTime; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/PaymentApplication.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/PaymentApplication.java new file mode 100644 index 0000000..1d6d033 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/PaymentApplication.java @@ -0,0 +1,76 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments from this software for such purposes. + * Copyright of this software remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is not liable for any claims arising from secondary or illegal development. + *

+ * 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.LocalDate; + +/** 付款申请实体。 @author Chill */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("blade_payment_application") +public class PaymentApplication extends TenantEntity { + @Serial private static final long serialVersionUID = 1L; + private String paymentNo; + private String paymentType; + private Long settlementId; + private String settlementNo; + private Long preSettlementId; + private String preSettlementNo; + 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 BigDecimal settlementAmount; + private BigDecimal payableAmount; + private String billType; + private BigDecimal paymentRatio; + private BigDecimal appliedAmount; + private String paymentMethod; + private Long billLedgerId; + private String billNo; + private Long receiptAccountId; + private String receiptAccountName; + private String bankName; + private String bankAccount; + private String applicantName; + private LocalDate applyDate; + private String invoiceStatus; + private BigDecimal matchedInvoiceAmount; + private BigDecimal paidAmount; + private String approvalStatus; + private String currentNode; + private String currentProcessor; + private String kingdeeBillNo; + private String kingdeeStatus; + private String attachmentsJson; + private String remark; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/PaymentApplicationInvoice.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/PaymentApplicationInvoice.java new file mode 100644 index 0000000..9a6ffdb --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/PaymentApplicationInvoice.java @@ -0,0 +1,47 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments from this software for such purposes. + * Copyright of this software remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is not liable for any claims arising from secondary or illegal development. + *

+ * 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.LocalDate; + +/** 付款申请发票明细。 @author Chill */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("blade_payment_application_invoice") +public class PaymentApplicationInvoice extends TenantEntity { + @Serial private static final long serialVersionUID = 1L; + private Long paymentApplicationId; + private Integer lineNo; + private String settlementNo; + private String invoiceNo; + private LocalDate invoiceDate; + private String invoiceType; + private BigDecimal taxRate; + private BigDecimal invoiceAmount; + private BigDecimal matchedAmount; + private String attachmentJson; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/PaymentApplicationRecord.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/PaymentApplicationRecord.java new file mode 100644 index 0000000..1c5c1af --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/PaymentApplicationRecord.java @@ -0,0 +1,43 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments from this software for such purposes. + * Copyright of this software remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is not liable for any claims arising from secondary or illegal development. + *

+ * 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.LocalDate; + +/** 付款申请付款记录。 @author Chill */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("blade_payment_application_record") +public class PaymentApplicationRecord extends TenantEntity { + @Serial private static final long serialVersionUID = 1L; + private Long paymentApplicationId; + private BigDecimal paidAmount; + private LocalDate paidDate; + private String paymentNo; + private String voucherJson; + private String kingdeeBillNo; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/ReceiptClaim.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/ReceiptClaim.java new file mode 100644 index 0000000..fc7f786 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/ReceiptClaim.java @@ -0,0 +1,74 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * Author: Chill Zhuang (bladejava@qq.com) + */ +package org.springblade.transport.pojo.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +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_receipt_claim") +@Schema(description = "收款流水认领") +public class ReceiptClaim extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + @JsonSerialize(using = ToStringSerializer.class) + private Long receiptFlowId; + private BigDecimal claimAmount; + @JsonSerialize(using = ToStringSerializer.class) + private Long claimerId; + private String claimerName; + @JsonSerialize(using = ToStringSerializer.class) + private Long claimerDeptId; + private String claimerDeptName; + private LocalDate claimDate; + private String attachmentsJson; + private String remark; + private String claimStatus; + private String kingdeeBillNo; + private String kingdeeBillStatus; + @JsonSerialize(using = ToStringSerializer.class) + private Long voidedBy; + private String voidedByName; + private LocalDateTime voidedTime; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/ReceiptClaimSettlement.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/ReceiptClaimSettlement.java new file mode 100644 index 0000000..44df9c6 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/ReceiptClaimSettlement.java @@ -0,0 +1,63 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * Author: Chill Zhuang (bladejava@qq.com) + */ +package org.springblade.transport.pojo.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +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_receipt_claim_settlement") +@Schema(description = "收款认领结算单分摊") +public class ReceiptClaimSettlement extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + @JsonSerialize(using = ToStringSerializer.class) + private Long receiptClaimId; + @JsonSerialize(using = ToStringSerializer.class) + private Long receiptFlowId; + @JsonSerialize(using = ToStringSerializer.class) + private Long formalSettlementId; + private String formalSettlementNo; + private BigDecimal settlementAmount; + private BigDecimal claimedReceiptAmount; + private BigDecimal allocatedReceiptAmount; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/ReceiptFlowRecord.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/ReceiptFlowRecord.java new file mode 100644 index 0000000..2fbe069 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/ReceiptFlowRecord.java @@ -0,0 +1,64 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * Author: Chill Zhuang (bladejava@qq.com) + */ +package org.springblade.transport.pojo.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +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_receipt_flow_record") +@Schema(description = "收款流水操作留痕") +public class ReceiptFlowRecord extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + @JsonSerialize(using = ToStringSerializer.class) + private Long receiptFlowId; + @JsonSerialize(using = ToStringSerializer.class) + private Long receiptClaimId; + private String actionType; + private String actionName; + private String fromStatus; + private String toStatus; + private BigDecimal operationAmount; + private String operatorName; + private String content; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/BillLedgerVO.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/BillLedgerVO.java new file mode 100644 index 0000000..96cf8a4 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/BillLedgerVO.java @@ -0,0 +1,31 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + */ +package org.springblade.transport.pojo.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springblade.transport.pojo.entity.BillLedger; +import org.springblade.transport.pojo.entity.BillLedgerUsage; + +import java.io.Serial; +import java.time.LocalDate; +import java.util.List; + +/** 汇票台账视图。 @author Chill */ +@Data +@EqualsAndHashCode(callSuper = true) +public class BillLedgerVO extends BillLedger { + @Serial private static final long serialVersionUID = 1L; + @TableField(exist = false) private LocalDate issueStartDate; + @TableField(exist = false) private LocalDate issueEndDate; + @TableField(exist = false) private String maturityStatus; + @TableField(exist = false) private String expiryShortcut; + @TableField(exist = false) private String billTypeName; + @TableField(exist = false) private String maturityStatusName; + @TableField(exist = false) private String createUserName; + @TableField(exist = false) private String updateUserName; + @TableField(exist = false) private List usageRecords; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/BillPaymentVO.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/BillPaymentVO.java new file mode 100644 index 0000000..9db1628 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/BillPaymentVO.java @@ -0,0 +1,46 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.BillPayment; + +import java.io.Serial; +import java.time.LocalDate; + +/** 汇票付款视图。 @author Chill */ +@Data +@EqualsAndHashCode(callSuper = true) +public class BillPaymentVO extends BillPayment { + @Serial private static final long serialVersionUID = 1L; + @TableField(exist = false) private LocalDate paymentStartDate; + @TableField(exist = false) private LocalDate paymentEndDate; + @TableField(exist = false) private String approvalStatusName; + @TableField(exist = false) private String createUserName; + @TableField(exist = false) private String updateUserName; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/InvoiceApplicationSheetVO.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/InvoiceApplicationSheetVO.java new file mode 100644 index 0000000..0b0dd2f --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/InvoiceApplicationSheetVO.java @@ -0,0 +1,47 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.InvoiceApplicationLine; +import org.springblade.transport.pojo.entity.InvoiceApplicationSheet; + +import java.io.Serial; +import java.util.List; + +/** + * 开票申请发票张次视图实体类 + * + * @author Chill + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class InvoiceApplicationSheetVO extends InvoiceApplicationSheet { + @Serial private static final long serialVersionUID = 1L; + @TableField(exist = false) private List lines; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/InvoiceApplicationVO.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/InvoiceApplicationVO.java new file mode 100644 index 0000000..664d02b --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/InvoiceApplicationVO.java @@ -0,0 +1,56 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.InvoiceApplication; +import org.springblade.transport.pojo.entity.InvoiceApplicationDetail; +import org.springblade.transport.pojo.entity.InvoiceApplicationRecord; +import org.springblade.transport.pojo.entity.InvoiceApplicationSettlement; + +import java.io.Serial; +import java.util.List; + +/** + * 开票申请视图实体类 + * + * @author Chill + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class InvoiceApplicationVO extends InvoiceApplication { + @Serial private static final long serialVersionUID = 1L; + @TableField(exist = false) private String settlementNos; + @TableField(exist = false) private String approvalStatusName; + @TableField(exist = false) private String kingdeeStatusName; + @TableField(exist = false) private String createUserName; + @TableField(exist = false) private List settlements; + @TableField(exist = false) private List sheets; + @TableField(exist = false) private List details; + @TableField(exist = false) private List records; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/InvoiceReceiptVO.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/InvoiceReceiptVO.java new file mode 100644 index 0000000..8be4dcf --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/InvoiceReceiptVO.java @@ -0,0 +1,56 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.InvoiceReceipt; +import org.springblade.transport.pojo.entity.InvoiceReceiptRecord; +import org.springblade.transport.pojo.entity.InvoiceReceiptSettlement; + +import java.io.Serial; +import java.util.List; + +/** + * 收票登记视图实体类 + * + * @author Chill + */ +@Data +@EqualsAndHashCode(callSuper = true) +@Schema(description = "收票登记视图实体类") +public class InvoiceReceiptVO extends InvoiceReceipt { + @Serial private static final long serialVersionUID = 1L; + @TableField(exist = false) private String settlementNos; + @TableField(exist = false) private String approvalStatusName; + @TableField(exist = false) private String kingdeeStatusName; + @TableField(exist = false) private String createUserName; + @TableField(exist = false) private String updateUserName; + @TableField(exist = false) private List settlements; + @TableField(exist = false) private List records; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/PaymentApplicationVO.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/PaymentApplicationVO.java new file mode 100644 index 0000000..cbacc29 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/PaymentApplicationVO.java @@ -0,0 +1,47 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments from this software for such purposes. + * Copyright of this software remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is not liable for any claims arising from secondary or illegal development. + *

+ * 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.PaymentApplication; +import org.springblade.transport.pojo.entity.PaymentApplicationInvoice; +import org.springblade.transport.pojo.entity.PaymentApplicationRecord; + +import java.io.Serial; +import java.time.LocalDate; +import java.util.List; + +/** 付款申请视图。 @author Chill */ +@Data +@EqualsAndHashCode(callSuper = true) +public class PaymentApplicationVO extends PaymentApplication { + @Serial private static final long serialVersionUID = 1L; + @TableField(exist = false) private LocalDate applyStartDate; + @TableField(exist = false) private LocalDate applyEndDate; + @TableField(exist = false) private String createUserName; + @TableField(exist = false) private String updateUserName; + @TableField(exist = false) private String paymentTypeName; + @TableField(exist = false) private String approvalStatusName; + @TableField(exist = false) private String kingdeeStatusName; + @TableField(exist = false) private List invoices; + @TableField(exist = false) private List paymentRecords; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/ReceiptClaimRecordVO.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/ReceiptClaimRecordVO.java new file mode 100644 index 0000000..9802b66 --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/ReceiptClaimRecordVO.java @@ -0,0 +1,93 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.ReceiptClaim; +import org.springblade.transport.pojo.entity.ReceiptClaimSettlement; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serial; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 认领记录视图实体类 + * + * @author Chill + */ +@Data +@EqualsAndHashCode(callSuper = true) +@Schema(description = "认领记录视图实体类") +public class ReceiptClaimRecordVO extends ReceiptClaim { + + @Serial + private static final long serialVersionUID = 1L; + + @TableField(exist = false) + private String receiptNoticeNo; + @TableField(exist = false) + private String payerName; + @TableField(exist = false) + private BigDecimal receiptAmount; + @TableField(exist = false) + private String counterpartyName; + @TableField(exist = false) + private String counterpartyAccount; + @TableField(exist = false) + private String counterpartyBank; + @TableField(exist = false) + private String summary; + @TableField(exist = false) + private LocalDateTime transactionTime; + @TableField(exist = false) + private String detailSerialNo; + @TableField(exist = false) + private String associatedSettlementNos; + @TableField(exist = false) + private String claimStatusName; + @TableField(exist = false) + private String kingdeeBillStatusName; + @TableField(exist = false) + private List settlements; + @TableField(exist = false) + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate transactionStartDate; + @TableField(exist = false) + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate transactionEndDate; + @TableField(exist = false) + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate claimStartDate; + @TableField(exist = false) + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate claimEndDate; +} diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/ReceiptFlowVO.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/ReceiptFlowVO.java new file mode 100644 index 0000000..caa11ce --- /dev/null +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/vo/ReceiptFlowVO.java @@ -0,0 +1,73 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.KingdeeReceiptFlow; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serial; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; + +/** + * 收款流水视图实体类 + * + * @author Chill + */ +@Data +@EqualsAndHashCode(callSuper = true) +@Schema(description = "收款流水视图实体类") +public class ReceiptFlowVO extends KingdeeReceiptFlow { + + @Serial + private static final long serialVersionUID = 1L; + + @TableField(exist = false) + private String claimStatusName; + @TableField(exist = false) + private BigDecimal remainingAmount; + @TableField(exist = false) + private String createUserName; + @TableField(exist = false) + private String updateUserName; + @TableField(exist = false) + private String claimerName; + @TableField(exist = false) + private String claimerDeptName; + @TableField(exist = false) + private LocalDate claimDate; + @TableField(exist = false) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime transactionStartTime; + @TableField(exist = false) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime transactionEndTime; +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/BillLedgerController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/BillLedgerController.java new file mode 100644 index 0000000..c699cdb --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/BillLedgerController.java @@ -0,0 +1,82 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + */ +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.BillLedgerSaveRequest; +import org.springblade.transport.pojo.vo.BillLedgerVO; +import org.springblade.transport.service.IBillLedgerService; +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 = "bill_ledger") +@RequestMapping("/bill-ledger") +@Tag(name = "汇票台账", description = "汇票票据信息及可用余额管理") +public class BillLedgerController extends BladeController { + private final IBillLedgerService billLedgerService; + + @GetMapping("/list") + @ApiOperationSupport(order = 1) + @Operation(summary = "汇票台账分页") + public R> list(BillLedgerVO query, Query pageQuery) { + return R.data(billLedgerService.selectPage(Condition.getPage(pageQuery), query)); + } + + @GetMapping("/detail") + @ApiOperationSupport(order = 2) + @Operation(summary = "汇票台账详情") + public R detail(@RequestParam Long id) { + return R.data(billLedgerService.detail(id)); + } + + @GetMapping("/expiry-counts") + @ApiOperationSupport(order = 3) + @Operation(summary = "汇票到期快捷统计") + public R> expiryCounts() { + return R.data(billLedgerService.expiryCounts()); + } + + @GetMapping("/available-options") + @ApiOperationSupport(order = 4) + @Operation(summary = "付款申请可用汇票") + public R> availableOptions(@RequestParam(required = false) String keyword, + @RequestParam(required = false) Long deptId, @RequestParam(required = false) Long selectedId) { + return R.data(billLedgerService.availableOptions(keyword, deptId, selectedId)); + } + + @PostMapping("/submit") + @ApiOperationSupport(order = 5) + @Operation(summary = "新增或编辑汇票台账") + public R submit(@RequestBody BillLedgerSaveRequest request) { + return R.data(billLedgerService.submit(request)); + } + + @PostMapping("/remove") + @ApiOperationSupport(order = 6) + @Operation(summary = "删除汇票台账") + public R remove(@RequestParam Long id) { + billLedgerService.removeLedger(id); + return R.success("删除成功"); + } +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/BillPaymentController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/BillPaymentController.java new file mode 100644 index 0000000..3c1f3b4 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/BillPaymentController.java @@ -0,0 +1,118 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.BillPaymentSaveRequest; +import org.springblade.transport.pojo.dto.BillPaymentStatusRequest; +import org.springblade.transport.pojo.vo.BillPaymentVO; +import org.springblade.transport.service.IBillPaymentService; +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; + +/** 汇票付款控制器。 @author Chill */ +@RestController +@AllArgsConstructor +@PreAuth(menu = "bill_payment") +@RequestMapping("/bill-payment") +@Tag(name = "汇票付款", description = "汇票付款单据管理") +public class BillPaymentController extends BladeController { + private final IBillPaymentService billPaymentService; + + @GetMapping("/list") + @ApiOperationSupport(order = 1) + @Operation(summary = "汇票付款分页") + public R> list(BillPaymentVO query, Query pageQuery) { + return R.data(billPaymentService.selectPage(Condition.getPage(pageQuery), query)); + } + + @GetMapping("/detail") + @ApiOperationSupport(order = 2) + @Operation(summary = "汇票付款详情") + public R detail(@RequestParam Long id) { + return R.data(billPaymentService.detail(id)); + } + + @PostMapping("/save") + @ApiOperationSupport(order = 3) + @Operation(summary = "保存汇票付款") + public R save(@RequestBody BillPaymentSaveRequest request) { + return R.data(billPaymentService.saveDraft(request)); + } + + @PostMapping("/remove") + @ApiOperationSupport(order = 4) + @Operation(summary = "删除汇票付款草稿") + public R remove(@RequestParam Long id) { + billPaymentService.removeDraft(id); + return R.success("删除成功"); + } + + @PostMapping("/submit") + @ApiOperationSupport(order = 5) + @Operation(summary = "提交汇票付款") + public R submit(@RequestBody BillPaymentStatusRequest request) { + billPaymentService.submit(request); + return R.success("提交成功"); + } + + @PostMapping("/approve") + @ApiOperationSupport(order = 6) + @Operation(summary = "审批通过汇票付款") + public R approve(@RequestBody BillPaymentStatusRequest request) { + billPaymentService.approve(request); + return R.success("审批通过"); + } + + @PostMapping("/return") + @ApiOperationSupport(order = 7) + @Operation(summary = "驳回汇票付款") + public R returnBill(@RequestBody BillPaymentStatusRequest request) { + billPaymentService.returnBill(request); + return R.success("已驳回"); + } + + @PostMapping("/void") + @ApiOperationSupport(order = 8) + @Operation(summary = "作废汇票付款") + public R voidBill(@RequestBody BillPaymentStatusRequest request) { + billPaymentService.voidBill(request); + return R.success("作废成功"); + } +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/InvoiceApplicationController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/InvoiceApplicationController.java new file mode 100644 index 0000000..35ddac0 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/InvoiceApplicationController.java @@ -0,0 +1,154 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.InvoiceApplicationSaveRequest; +import org.springblade.transport.pojo.dto.InvoiceApplicationStatusRequest; +import org.springblade.transport.pojo.entity.FormalSettlementDetail; +import org.springblade.transport.pojo.vo.InvoiceApplicationVO; +import org.springblade.transport.service.IInvoiceApplicationService; +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 = "invoice_application") +@RequestMapping("/invoice-application") +@Tag(name = "开票管理", description = "开票申请管理") +public class InvoiceApplicationController extends BladeController { + private final IInvoiceApplicationService invoiceApplicationService; + + @GetMapping("/list") + @ApiOperationSupport(order = 1) + @Operation(summary = "开票申请分页") + public R> list(InvoiceApplicationVO query, Query pageQuery) { + return R.data(invoiceApplicationService.selectPage(Condition.getPage(pageQuery), query)); + } + + @GetMapping("/detail") + @ApiOperationSupport(order = 2) + @Operation(summary = "开票申请详情") + public R detail(@RequestParam Long id) { + return R.data(invoiceApplicationService.detail(id)); + } + + @GetMapping("/settlement-candidates") + @ApiOperationSupport(order = 3) + @Operation(summary = "可开票正式结算单") + public R>> settlementCandidates(@RequestParam(required = false) String keyword) { + return R.data(invoiceApplicationService.settlementCandidates(keyword)); + } + + @GetMapping("/settlement-details") + @ApiOperationSupport(order = 4) + @Operation(summary = "结算单可选明细") + public R> settlementDetails(@RequestParam String settlementIds) { + return R.data(invoiceApplicationService.settlementDetails(settlementIds)); + } + + @GetMapping("/receiver-information") + @ApiOperationSupport(order = 5) + @Operation(summary = "受票方开票信息") + public R> receiverInformation(@RequestParam String settlementIds) { + return R.data(invoiceApplicationService.receiverInformation(settlementIds)); + } + + @PostMapping("/save") + @ApiOperationSupport(order = 6) + @Operation(summary = "保存开票申请") + public R save(@RequestBody InvoiceApplicationSaveRequest request) { + return R.data(invoiceApplicationService.saveDraft(request)); + } + + @PostMapping("/remove") + @ApiOperationSupport(order = 7) + @Operation(summary = "删除开票申请草稿") + public R remove(@RequestParam Long id) { + invoiceApplicationService.removeDraft(id); + return R.success("删除成功"); + } + + @PostMapping("/submit") + @ApiOperationSupport(order = 8) + @Operation(summary = "提交开票申请") + public R submit(@RequestBody InvoiceApplicationStatusRequest request) { + invoiceApplicationService.submit(request); + return R.success("提交成功"); + } + + @PostMapping("/approve") + @ApiOperationSupport(order = 9) + @Operation(summary = "审批通过开票申请") + public R approve(@RequestBody InvoiceApplicationStatusRequest request) { + invoiceApplicationService.approve(request); + return R.success("审批通过"); + } + + @PostMapping("/return") + @ApiOperationSupport(order = 10) + @Operation(summary = "驳回开票申请") + public R returnBill(@RequestBody InvoiceApplicationStatusRequest request) { + invoiceApplicationService.returnBill(request); + return R.success("已驳回"); + } + + @PostMapping("/void") + @ApiOperationSupport(order = 11) + @Operation(summary = "作废开票申请") + public R voidBill(@RequestBody InvoiceApplicationStatusRequest request) { + invoiceApplicationService.voidBill(request); + return R.success("作废成功"); + } + + @PostMapping("/sync-kingdee") + @ApiOperationSupport(order = 12) + @Operation(summary = "同步金蝶开票申请") + public R syncKingdee(@RequestParam Long id) { + return R.data(invoiceApplicationService.syncKingdee(id)); + } +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/InvoiceReceiptController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/InvoiceReceiptController.java new file mode 100644 index 0000000..1a01d3c --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/InvoiceReceiptController.java @@ -0,0 +1,157 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.InvoiceReceiptSaveRequest; +import org.springblade.transport.pojo.dto.InvoiceReceiptStatusRequest; +import org.springblade.transport.pojo.entity.KingdeeInvoicePool; +import org.springblade.transport.pojo.vo.InvoiceReceiptVO; +import org.springblade.transport.service.IInvoiceReceiptService; +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 = "invoice_receipt") +@RequestMapping("/invoice-receipt") +@Tag(name = "收票管理", description = "进项发票登记认领管理") +public class InvoiceReceiptController extends BladeController { + + private final IInvoiceReceiptService invoiceReceiptService; + + @GetMapping("/list") + @ApiOperationSupport(order = 1) + @Operation(summary = "收票登记分页") + public R> list(InvoiceReceiptVO query, Query pageQuery) { + return R.data(invoiceReceiptService.selectPage(Condition.getPage(pageQuery), query)); + } + + @GetMapping("/detail") + @ApiOperationSupport(order = 2) + @Operation(summary = "收票登记详情") + public R detail(@RequestParam Long id) { + return R.data(invoiceReceiptService.detail(id)); + } + + @GetMapping("/invoice-pool") + @ApiOperationSupport(order = 3) + @Operation(summary = "查询金蝶进项发票票据池") + public R> invoicePool(@RequestParam(required = false) String keyword) { + return R.data(invoiceReceiptService.invoicePool(keyword)); + } + + @GetMapping("/settlement-candidates") + @ApiOperationSupport(order = 4) + @Operation(summary = "可关联的应付正式结算单") + public R>> settlementCandidates( + @RequestParam(required = false) String keyword, + @RequestParam(required = false) Long receiptId) { + return R.data(invoiceReceiptService.settlementCandidates(keyword, receiptId)); + } + + @GetMapping("/reference-information") + @ApiOperationSupport(order = 5) + @Operation(summary = "收票关联参考信息") + public R> referenceInformation(@RequestParam String settlementIds) { + return R.data(invoiceReceiptService.referenceInformation(settlementIds)); + } + + @PostMapping("/save") + @ApiOperationSupport(order = 6) + @Operation(summary = "保存收票登记") + public R save(@RequestBody InvoiceReceiptSaveRequest request) { + return R.data(invoiceReceiptService.saveDraft(request)); + } + + @PostMapping("/remove") + @ApiOperationSupport(order = 7) + @Operation(summary = "删除收票登记草稿") + public R remove(@RequestParam Long id) { + invoiceReceiptService.removeDraft(id); + return R.success("删除成功"); + } + + @PostMapping("/submit") + @ApiOperationSupport(order = 8) + @Operation(summary = "提交收票登记") + public R submit(@RequestBody InvoiceReceiptStatusRequest request) { + invoiceReceiptService.submit(request); + return R.success("提交成功"); + } + + @PostMapping("/approve") + @ApiOperationSupport(order = 9) + @Operation(summary = "审批通过收票登记") + public R approve(@RequestBody InvoiceReceiptStatusRequest request) { + invoiceReceiptService.approve(request); + return R.success("审批通过"); + } + + @PostMapping("/return") + @ApiOperationSupport(order = 10) + @Operation(summary = "驳回收票登记") + public R returnBill(@RequestBody InvoiceReceiptStatusRequest request) { + invoiceReceiptService.returnBill(request); + return R.success("已驳回"); + } + + @PostMapping("/void") + @ApiOperationSupport(order = 11) + @Operation(summary = "作废收票登记") + public R voidBill(@RequestBody InvoiceReceiptStatusRequest request) { + invoiceReceiptService.voidBill(request); + return R.success("作废成功"); + } + + @PostMapping("/sync-kingdee") + @ApiOperationSupport(order = 12) + @Operation(summary = "同步金蝶发票状态") + public R syncKingdee(@RequestParam Long id) { + return R.data(invoiceReceiptService.syncKingdee(id)); + } +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/PaymentApplicationController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/PaymentApplicationController.java new file mode 100644 index 0000000..575bf17 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/PaymentApplicationController.java @@ -0,0 +1,87 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments from this software for such purposes. + * Copyright of this software remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is not liable for any claims arising from secondary or illegal development. + *

+ * 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.PaymentApplicationSaveRequest; +import org.springblade.transport.pojo.dto.PaymentApplicationStatusRequest; +import org.springblade.transport.pojo.vo.PaymentApplicationVO; +import org.springblade.transport.service.IPaymentApplicationService; +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; + +/** 付款申请控制器。 @author Chill */ +@RestController +@AllArgsConstructor +@PreAuth(menu = "payment_application") +@RequestMapping("/payment-application") +@Tag(name = "付款管理", description = "付款申请管理") +public class PaymentApplicationController extends BladeController { + private final IPaymentApplicationService paymentApplicationService; + @GetMapping("/list") + @ApiOperationSupport(order = 1) + @Operation(summary = "付款申请分页") + public R> list(PaymentApplicationVO query, Query pageQuery) { return R.data(paymentApplicationService.selectPage(Condition.getPage(pageQuery), query)); } + @GetMapping("/detail") + @ApiOperationSupport(order = 2) + @Operation(summary = "付款申请详情") + public R detail(@RequestParam Long id) { return R.data(paymentApplicationService.detail(id)); } + @PostMapping("/save") + @ApiOperationSupport(order = 3) + @Operation(summary = "保存付款申请") + public R save(@RequestBody PaymentApplicationSaveRequest request) { return R.data(paymentApplicationService.saveDraft(request)); } + @PostMapping("/remove") + @ApiOperationSupport(order = 4) + @Operation(summary = "删除付款申请草稿") + public R remove(@RequestParam Long id) { paymentApplicationService.removeDraft(id); return R.success("删除成功"); } + @PostMapping("/submit") + @ApiOperationSupport(order = 5) + @Operation(summary = "提交付款申请") + public R submit(@RequestBody PaymentApplicationStatusRequest request) { paymentApplicationService.submit(request); return R.success("提交成功"); } + @PostMapping("/approve") + @ApiOperationSupport(order = 6) + @Operation(summary = "审批通过付款申请") + public R approve(@RequestBody PaymentApplicationStatusRequest request) { paymentApplicationService.approve(request); return R.success("审批通过"); } + @PostMapping("/return") + @ApiOperationSupport(order = 7) + @Operation(summary = "驳回付款申请") + public R returnBill(@RequestBody PaymentApplicationStatusRequest request) { paymentApplicationService.returnBill(request); return R.success("已驳回"); } + @PostMapping("/void") + @ApiOperationSupport(order = 8) + @Operation(summary = "作废付款申请") + public R voidBill(@RequestBody PaymentApplicationStatusRequest request) { paymentApplicationService.voidBill(request); return R.success("作废成功"); } + @PostMapping("/sync-kingdee") + @ApiOperationSupport(order = 9) + @Operation(summary = "生成金蝶付款单") + public R syncKingdee(@RequestParam Long id) { return R.data(paymentApplicationService.syncKingdee(id)); } +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/ReceiptClaimRecordController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/ReceiptClaimRecordController.java new file mode 100644 index 0000000..7cfd3f8 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/ReceiptClaimRecordController.java @@ -0,0 +1,90 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.ReceiptClaimAttachmentsRequest; +import org.springblade.transport.pojo.vo.ReceiptClaimRecordVO; +import org.springblade.transport.service.IReceiptClaimRecordService; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * 认领记录控制器 + * + * @author Chill + */ +@RestController +@AllArgsConstructor +@PreAuth(menu = "receipt_claim_record") +@RequestMapping("/receipt-claim-record") +@Tag(name = "认领记录", description = "当前用户收款认领记录查询与作废") +public class ReceiptClaimRecordController extends BladeController { + + private final IReceiptClaimRecordService receiptClaimRecordService; + + @GetMapping("/list") + @ApiOperationSupport(order = 1) + @Operation(summary = "当前用户认领记录分页") + public R> list(ReceiptClaimRecordVO query, Query pageQuery) { + return R.data(receiptClaimRecordService.selectPage(Condition.getPage(pageQuery), query)); + } + + @GetMapping("/detail") + @ApiOperationSupport(order = 2) + @Operation(summary = "认领记录详情") + public R detail(@RequestParam Long id) { + return R.data(receiptClaimRecordService.detail(id)); + } + + @PostMapping("/attachments") + @ApiOperationSupport(order = 3) + @Operation(summary = "维护本人认领记录附件") + public R updateAttachments(@RequestBody ReceiptClaimAttachmentsRequest request) { + receiptClaimRecordService.updateAttachments(request); + return R.success(); + } + + @PostMapping("/void") + @ApiOperationSupport(order = 4) + @Operation(summary = "作废认领记录并生成金蝶认领冲单") + public R voidClaim(@RequestParam Long id) { + return R.data(receiptClaimRecordService.voidClaim(id)); + } +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/ReceiptFlowController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/ReceiptFlowController.java new file mode 100644 index 0000000..4aa3f02 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/ReceiptFlowController.java @@ -0,0 +1,102 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.ReceiptClaimRequest; +import org.springblade.transport.pojo.dto.ReceiptFlowSyncRequest; +import org.springblade.transport.pojo.vo.ReceiptFlowVO; +import org.springblade.transport.service.IReceiptFlowService; +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 = "receipt_flow") +@RequestMapping("/receipt-flow") +@Tag(name = "收款流水", description = "金蝶收款流水同步与认领管理") +public class ReceiptFlowController extends BladeController { + + private final IReceiptFlowService receiptFlowService; + + @GetMapping("/list") + @ApiOperationSupport(order = 1) + @Operation(summary = "收款流水分页") + public R> list(ReceiptFlowVO query, Query pageQuery) { + return R.data(receiptFlowService.selectPage(Condition.getPage(pageQuery), query)); + } + + @GetMapping("/detail") + @ApiOperationSupport(order = 2) + @Operation(summary = "收款流水详情") + public R detail(@RequestParam Long id) { + return R.data(receiptFlowService.detail(id)); + } + + @GetMapping("/settlement-candidates") + @ApiOperationSupport(order = 3) + @Operation(summary = "可关联的应收正式结算单") + public R>> settlementCandidates( + @RequestParam(required = false) String keyword, + @RequestParam Long flowId) { + return R.data(receiptFlowService.settlementCandidates(keyword, flowId)); + } + + @PostMapping("/claim") + @ApiOperationSupport(order = 4) + @Operation(summary = "认领收款流水") + public R claim(@RequestBody ReceiptClaimRequest request) { + return R.data(receiptFlowService.claim(request)); + } + + @PostMapping("/sync") + @ApiOperationSupport(order = 5) + @Operation(summary = "手动同步金蝶收款流水") + public R sync(@RequestBody(required = false) ReceiptFlowSyncRequest request) { + return R.data(receiptFlowService.sync(request)); + } +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/BillLedgerMapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/BillLedgerMapper.java new file mode 100644 index 0000000..15a7948 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/BillLedgerMapper.java @@ -0,0 +1,14 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + */ +package org.springblade.transport.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.springblade.transport.pojo.entity.BillLedger; + +/** 汇票台账 Mapper。 @author Chill */ +@Mapper +public interface BillLedgerMapper extends BaseMapper { +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/BillLedgerUsageMapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/BillLedgerUsageMapper.java new file mode 100644 index 0000000..49915d1 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/BillLedgerUsageMapper.java @@ -0,0 +1,14 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + */ +package org.springblade.transport.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.springblade.transport.pojo.entity.BillLedgerUsage; + +/** 汇票使用记录 Mapper。 @author Chill */ +@Mapper +public interface BillLedgerUsageMapper extends BaseMapper { +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/BillPaymentMapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/BillPaymentMapper.java new file mode 100644 index 0000000..2b2db97 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/BillPaymentMapper.java @@ -0,0 +1,35 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.BillPayment; + +/** 汇票付款 Mapper。 @author Chill */ +@Mapper +public interface BillPaymentMapper extends BaseMapper { +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationDetailMapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationDetailMapper.java new file mode 100644 index 0000000..bdfc170 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationDetailMapper.java @@ -0,0 +1,39 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.InvoiceApplicationDetail; + +/** + * 开票申请结算明细 Mapper 接口 + * + * @author Chill + */ +@Mapper +public interface InvoiceApplicationDetailMapper extends BaseMapper { +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationLineMapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationLineMapper.java new file mode 100644 index 0000000..412052f --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationLineMapper.java @@ -0,0 +1,39 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.InvoiceApplicationLine; + +/** + * 开票申请商品行 Mapper 接口 + * + * @author Chill + */ +@Mapper +public interface InvoiceApplicationLineMapper extends BaseMapper { +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationMapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationMapper.java new file mode 100644 index 0000000..9e9db78 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationMapper.java @@ -0,0 +1,39 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.InvoiceApplication; + +/** + * 开票申请 Mapper 接口 + * + * @author Chill + */ +@Mapper +public interface InvoiceApplicationMapper extends BaseMapper { +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationRecordMapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationRecordMapper.java new file mode 100644 index 0000000..b3666bc --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationRecordMapper.java @@ -0,0 +1,39 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.InvoiceApplicationRecord; + +/** + * 开票申请操作记录 Mapper 接口 + * + * @author Chill + */ +@Mapper +public interface InvoiceApplicationRecordMapper extends BaseMapper { +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationSettlementMapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationSettlementMapper.java new file mode 100644 index 0000000..1cc35ba --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationSettlementMapper.java @@ -0,0 +1,39 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.InvoiceApplicationSettlement; + +/** + * 开票申请结算单 Mapper 接口 + * + * @author Chill + */ +@Mapper +public interface InvoiceApplicationSettlementMapper extends BaseMapper { +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationSheetMapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationSheetMapper.java new file mode 100644 index 0000000..6715132 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceApplicationSheetMapper.java @@ -0,0 +1,39 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.InvoiceApplicationSheet; + +/** + * 开票申请发票张次 Mapper 接口 + * + * @author Chill + */ +@Mapper +public interface InvoiceApplicationSheetMapper extends BaseMapper { +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceReceiptMapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceReceiptMapper.java new file mode 100644 index 0000000..eb554ae --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceReceiptMapper.java @@ -0,0 +1,39 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.InvoiceReceipt; + +/** + * 收票登记 Mapper 接口 + * + * @author Chill + */ +@Mapper +public interface InvoiceReceiptMapper extends BaseMapper { +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceReceiptRecordMapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceReceiptRecordMapper.java new file mode 100644 index 0000000..bd7501f --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceReceiptRecordMapper.java @@ -0,0 +1,39 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.InvoiceReceiptRecord; + +/** + * 收票登记操作记录 Mapper 接口 + * + * @author Chill + */ +@Mapper +public interface InvoiceReceiptRecordMapper extends BaseMapper { +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceReceiptSettlementMapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceReceiptSettlementMapper.java new file mode 100644 index 0000000..3a26ea7 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/InvoiceReceiptSettlementMapper.java @@ -0,0 +1,39 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.InvoiceReceiptSettlement; + +/** + * 收票登记结算单分摊 Mapper 接口 + * + * @author Chill + */ +@Mapper +public interface InvoiceReceiptSettlementMapper extends BaseMapper { +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/KingdeeInvoicePoolMapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/KingdeeInvoicePoolMapper.java new file mode 100644 index 0000000..d299c63 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/KingdeeInvoicePoolMapper.java @@ -0,0 +1,39 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.KingdeeInvoicePool; + +/** + * 金蝶进项发票票据池 Mapper 接口 + * + * @author Chill + */ +@Mapper +public interface KingdeeInvoicePoolMapper extends BaseMapper { +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/KingdeeReceiptFlowMapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/KingdeeReceiptFlowMapper.java new file mode 100644 index 0000000..7d69772 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/KingdeeReceiptFlowMapper.java @@ -0,0 +1,39 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.KingdeeReceiptFlow; + +/** + * 金蝶收款流水镜像 Mapper 接口 + * + * @author Chill + */ +@Mapper +public interface KingdeeReceiptFlowMapper extends BaseMapper { +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/PaymentApplicationInvoiceMapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/PaymentApplicationInvoiceMapper.java new file mode 100644 index 0000000..21c8c0a --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/PaymentApplicationInvoiceMapper.java @@ -0,0 +1,29 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments from this software for such purposes. + * Copyright of this software remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is not liable for any claims arising from secondary or illegal development. + *

+ * 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.PaymentApplicationInvoice; + +/** 付款申请发票 Mapper。 @author Chill */ +@Mapper +public interface PaymentApplicationInvoiceMapper extends BaseMapper { +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/PaymentApplicationMapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/PaymentApplicationMapper.java new file mode 100644 index 0000000..770dc20 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/PaymentApplicationMapper.java @@ -0,0 +1,29 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments from this software for such purposes. + * Copyright of this software remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is not liable for any claims arising from secondary or illegal development. + *

+ * 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.PaymentApplication; + +/** 付款申请 Mapper。 @author Chill */ +@Mapper +public interface PaymentApplicationMapper extends BaseMapper { +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/PaymentApplicationRecordMapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/PaymentApplicationRecordMapper.java new file mode 100644 index 0000000..dd9dfb8 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/PaymentApplicationRecordMapper.java @@ -0,0 +1,29 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments from this software for such purposes. + * Copyright of this software remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is not liable for any claims arising from secondary or illegal development. + *

+ * 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.PaymentApplicationRecord; + +/** 付款申请付款记录 Mapper。 @author Chill */ +@Mapper +public interface PaymentApplicationRecordMapper extends BaseMapper { +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/ReceiptClaimMapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/ReceiptClaimMapper.java new file mode 100644 index 0000000..cf0fd17 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/ReceiptClaimMapper.java @@ -0,0 +1,50 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * Author: Chill Zhuang (bladejava@qq.com) + */ +package org.springblade.transport.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springblade.transport.pojo.entity.ReceiptClaim; +import org.springblade.transport.pojo.vo.ReceiptClaimRecordVO; + +import java.util.List; + +/** + * 收款流水认领 Mapper 接口 + * + * @author Chill + */ +@Mapper +public interface ReceiptClaimMapper extends BaseMapper { + + List selectClaimRecordPage(IPage page, + @Param("query") ReceiptClaimRecordVO query, @Param("claimerId") Long claimerId); + + ReceiptClaimRecordVO selectClaimRecordDetail(@Param("id") Long id, + @Param("claimerId") Long claimerId); +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/ReceiptClaimMapper.xml b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/ReceiptClaimMapper.xml new file mode 100644 index 0000000..07a2553 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/ReceiptClaimMapper.xml @@ -0,0 +1,114 @@ + + + + + + c.id, + c.tenant_id, + c.create_user, + c.create_dept, + c.create_time, + c.update_user, + c.update_time, + c.status, + c.is_deleted, + c.receipt_flow_id, + c.claim_amount, + c.claimer_id, + c.claimer_name, + c.claimer_dept_id, + c.claimer_dept_name, + c.claim_date, + c.attachments_json, + c.remark, + c.claim_status, + c.kingdee_bill_no, + c.kingdee_bill_status, + c.voided_by, + c.voided_by_name, + c.voided_time, + f.receipt_notice_no, + f.payer_name, + f.receipt_amount, + f.counterparty_name, + f.counterparty_account, + f.counterparty_bank, + f.summary, + f.transaction_time, + f.detail_serial_no, + (SELECT GROUP_CONCAT(rcs.formal_settlement_no ORDER BY rcs.id SEPARATOR ',') + FROM blade_receipt_claim_settlement rcs + WHERE rcs.receipt_claim_id = c.id AND rcs.is_deleted = 0) AS associated_settlement_nos + + + + c.is_deleted = 0 + AND f.is_deleted = 0 + AND c.claimer_id = #{claimerId} + + + AND f.receipt_notice_no LIKE #{receiptNoticeNoLike} + + + + AND f.counterparty_name LIKE #{counterpartyNameLike} + + + + AND f.counterparty_bank LIKE #{counterpartyBankLike} + + + + AND f.counterparty_account LIKE #{counterpartyAccountLike} + + + + AND f.summary LIKE #{summaryLike} + + + AND c.claim_status = #{query.claimStatus} + + + AND f.transaction_time >= #{query.transactionStartDate} + + + AND f.transaction_time < DATE_ADD(#{query.transactionEndDate}, INTERVAL 1 DAY) + + + + AND c.claimer_name LIKE #{claimerNameLike} + + + AND c.claim_date >= #{query.claimStartDate} + + + AND c.claim_date <= #{query.claimEndDate} + + + + AND c.claimer_dept_name LIKE #{claimerDeptNameLike} + + + AND c.kingdee_bill_status = #{query.kingdeeBillStatus} + + + + + + + + diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/ReceiptClaimSettlementMapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/ReceiptClaimSettlementMapper.java new file mode 100644 index 0000000..3537992 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/ReceiptClaimSettlementMapper.java @@ -0,0 +1,39 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.ReceiptClaimSettlement; + +/** + * 收款认领结算单分摊 Mapper 接口 + * + * @author Chill + */ +@Mapper +public interface ReceiptClaimSettlementMapper extends BaseMapper { +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/ReceiptFlowRecordMapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/ReceiptFlowRecordMapper.java new file mode 100644 index 0000000..2f05829 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/ReceiptFlowRecordMapper.java @@ -0,0 +1,39 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.ReceiptFlowRecord; + +/** + * 收款流水操作留痕 Mapper 接口 + * + * @author Chill + */ +@Mapper +public interface ReceiptFlowRecordMapper extends BaseMapper { +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IBillLedgerService.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IBillLedgerService.java new file mode 100644 index 0000000..c31abd0 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IBillLedgerService.java @@ -0,0 +1,24 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + */ +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.BillLedgerSaveRequest; +import org.springblade.transport.pojo.entity.BillLedger; +import org.springblade.transport.pojo.vo.BillLedgerVO; + +import java.util.List; +import java.util.Map; + +/** 汇票台账服务。 @author Chill */ +public interface IBillLedgerService extends BaseService { + IPage selectPage(IPage page, BillLedgerVO query); + BillLedgerVO detail(Long id); + Map expiryCounts(); + List availableOptions(String keyword, Long deptId, Long selectedId); + Long submit(BillLedgerSaveRequest request); + void removeLedger(Long id); +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IBillPaymentService.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IBillPaymentService.java new file mode 100644 index 0000000..089d064 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IBillPaymentService.java @@ -0,0 +1,45 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.BillPaymentSaveRequest; +import org.springblade.transport.pojo.dto.BillPaymentStatusRequest; +import org.springblade.transport.pojo.entity.BillPayment; +import org.springblade.transport.pojo.vo.BillPaymentVO; + +/** 汇票付款服务。 @author Chill */ +public interface IBillPaymentService extends BaseService { + IPage selectPage(IPage page, BillPaymentVO query); + BillPaymentVO detail(Long id); + Long saveDraft(BillPaymentSaveRequest request); + void removeDraft(Long id); + void submit(BillPaymentStatusRequest request); + void approve(BillPaymentStatusRequest request); + void returnBill(BillPaymentStatusRequest request); + void voidBill(BillPaymentStatusRequest request); +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IInvoiceApplicationService.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IInvoiceApplicationService.java new file mode 100644 index 0000000..fe65e70 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IInvoiceApplicationService.java @@ -0,0 +1,57 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.InvoiceApplicationSaveRequest; +import org.springblade.transport.pojo.dto.InvoiceApplicationStatusRequest; +import org.springblade.transport.pojo.entity.FormalSettlementDetail; +import org.springblade.transport.pojo.entity.InvoiceApplication; +import org.springblade.transport.pojo.vo.InvoiceApplicationVO; + +import java.util.List; +import java.util.Map; + +/** + * 开票申请服务 + * + * @author Chill + */ +public interface IInvoiceApplicationService extends BaseService { + IPage selectPage(IPage page, InvoiceApplicationVO query); + InvoiceApplicationVO detail(Long id); + List> settlementCandidates(String keyword); + List settlementDetails(String settlementIds); + Map receiverInformation(String settlementIds); + Long saveDraft(InvoiceApplicationSaveRequest request); + void removeDraft(Long id); + void submit(InvoiceApplicationStatusRequest request); + void approve(InvoiceApplicationStatusRequest request); + void returnBill(InvoiceApplicationStatusRequest request); + void voidBill(InvoiceApplicationStatusRequest request); + String syncKingdee(Long id); +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IInvoiceReceiptService.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IInvoiceReceiptService.java new file mode 100644 index 0000000..c6253ae --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IInvoiceReceiptService.java @@ -0,0 +1,69 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.InvoiceReceiptSaveRequest; +import org.springblade.transport.pojo.dto.InvoiceReceiptStatusRequest; +import org.springblade.transport.pojo.entity.InvoiceReceipt; +import org.springblade.transport.pojo.entity.KingdeeInvoicePool; +import org.springblade.transport.pojo.vo.InvoiceReceiptVO; + +import java.util.List; +import java.util.Map; + +/** + * 收票登记服务 + * + * @author Chill + */ +public interface IInvoiceReceiptService extends BaseService { + + IPage selectPage(IPage page, InvoiceReceiptVO query); + + InvoiceReceiptVO detail(Long id); + + List invoicePool(String keyword); + + List> settlementCandidates(String keyword, Long receiptId); + + Map referenceInformation(String settlementIds); + + Long saveDraft(InvoiceReceiptSaveRequest request); + + void removeDraft(Long id); + + void submit(InvoiceReceiptStatusRequest request); + + void approve(InvoiceReceiptStatusRequest request); + + void returnBill(InvoiceReceiptStatusRequest request); + + void voidBill(InvoiceReceiptStatusRequest request); + + String syncKingdee(Long id); +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IPaymentApplicationService.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IPaymentApplicationService.java new file mode 100644 index 0000000..7a9c0f4 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IPaymentApplicationService.java @@ -0,0 +1,40 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments from this software for such purposes. + * Copyright of this software remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is not liable for any claims arising from secondary or illegal development. + *

+ * 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.PaymentApplicationSaveRequest; +import org.springblade.transport.pojo.dto.PaymentApplicationStatusRequest; +import org.springblade.transport.pojo.entity.PaymentApplication; +import org.springblade.transport.pojo.vo.PaymentApplicationVO; + +/** 付款申请服务。 @author Chill */ +public interface IPaymentApplicationService extends BaseService { + IPage selectPage(IPage page, PaymentApplicationVO query); + PaymentApplicationVO detail(Long id); + Long saveDraft(PaymentApplicationSaveRequest request); + void removeDraft(Long id); + void submit(PaymentApplicationStatusRequest request); + void approve(PaymentApplicationStatusRequest request); + void returnBill(PaymentApplicationStatusRequest request); + void voidBill(PaymentApplicationStatusRequest request); + String syncKingdee(Long id); +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IReceiptClaimRecordService.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IReceiptClaimRecordService.java new file mode 100644 index 0000000..66a8886 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IReceiptClaimRecordService.java @@ -0,0 +1,49 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.ReceiptClaimAttachmentsRequest; +import org.springblade.transport.pojo.entity.ReceiptClaim; +import org.springblade.transport.pojo.vo.ReceiptClaimRecordVO; + +/** + * 认领记录服务 + * + * @author Chill + */ +public interface IReceiptClaimRecordService extends BaseService { + + IPage selectPage(IPage page, + ReceiptClaimRecordVO query); + + ReceiptClaimRecordVO detail(Long id); + + void updateAttachments(ReceiptClaimAttachmentsRequest request); + + String voidClaim(Long id); +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IReceiptFlowService.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IReceiptFlowService.java new file mode 100644 index 0000000..816990d --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IReceiptFlowService.java @@ -0,0 +1,54 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.ReceiptClaimRequest; +import org.springblade.transport.pojo.dto.ReceiptFlowSyncRequest; +import org.springblade.transport.pojo.entity.KingdeeReceiptFlow; +import org.springblade.transport.pojo.vo.ReceiptFlowVO; + +import java.util.List; +import java.util.Map; + +/** + * 收款流水服务 + * + * @author Chill + */ +public interface IReceiptFlowService extends BaseService { + + IPage selectPage(IPage page, ReceiptFlowVO query); + + ReceiptFlowVO detail(Long id); + + List> settlementCandidates(String keyword, Long flowId); + + Long claim(ReceiptClaimRequest request); + + int sync(ReceiptFlowSyncRequest request); +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/BillLedgerServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/BillLedgerServiceImpl.java new file mode 100644 index 0000000..e3645c2 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/BillLedgerServiceImpl.java @@ -0,0 +1,302 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + */ +package org.springblade.transport.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +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.tool.jackson.JsonUtil; +import org.springblade.core.tool.utils.Func; +import org.springblade.transport.mapper.BillLedgerMapper; +import org.springblade.transport.mapper.BillLedgerUsageMapper; +import org.springblade.transport.mapper.CustomerArchiveMapper; +import org.springblade.transport.pojo.dto.BillLedgerSaveRequest; +import org.springblade.transport.pojo.entity.BillLedger; +import org.springblade.transport.pojo.entity.BillLedgerUsage; +import org.springblade.transport.pojo.entity.CustomerArchive; +import org.springblade.transport.pojo.vo.BillLedgerVO; +import org.springblade.transport.service.IBillLedgerService; +import org.springblade.transport.wrapper.BillLedgerWrapper; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDate; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** 汇票台账服务实现。 @author Chill */ +@Service +@RequiredArgsConstructor +public class BillLedgerServiceImpl extends BaseServiceImpl + implements IBillLedgerService { + private static final String APPROVED = "approved"; + private final BillLedgerUsageMapper usageMapper; + private final CustomerArchiveMapper customerArchiveMapper; + + @Override + public IPage selectPage(IPage page, BillLedgerVO query) { + LocalDate today = LocalDate.now(); + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery() + .like(Func.isNotEmpty(query.getBillNo()), BillLedger::getBillNo, query.getBillNo()) + .ge(query.getIssueStartDate() != null, BillLedger::getIssueDate, query.getIssueStartDate()) + .le(query.getIssueEndDate() != null, BillLedger::getIssueDate, query.getIssueEndDate()) + .like(Func.isNotEmpty(query.getIssuerName()), BillLedger::getIssuerName, query.getIssuerName()) + .like(Func.isNotEmpty(query.getReceiverName()), BillLedger::getReceiverName, query.getReceiverName()) + .eq(Func.isNotEmpty(query.getBillType()), BillLedger::getBillType, query.getBillType()); + applyMaturityStatus(wrapper, query.getMaturityStatus(), today); + applyExpiryShortcut(wrapper, query.getExpiryShortcut(), today); + wrapper.orderByDesc(BillLedger::getCreateTime); + return page(page, wrapper).convert(item -> BillLedgerWrapper.build().entityVO(item)); + } + + @Override + public BillLedgerVO detail(Long id) { + BillLedgerVO vo = BillLedgerWrapper.build().entityVO(existing(id)); + vo.setUsageRecords(usageMapper.selectList(Wrappers.lambdaQuery() + .eq(BillLedgerUsage::getBillLedgerId, id) + .eq(BillLedgerUsage::getUsageStatus, APPROVED) + .orderByDesc(BillLedgerUsage::getCreateTime))); + return vo; + } + + @Override + public Map expiryCounts() { + LocalDate today = LocalDate.now(); + Map counts = new LinkedHashMap<>(); + counts.put("all", count()); + counts.put("within30", count(Wrappers.lambdaQuery() + .ge(BillLedger::getMaturityDate, today) + .le(BillLedger::getMaturityDate, today.plusDays(30)))); + counts.put("within90", count(Wrappers.lambdaQuery() + .gt(BillLedger::getMaturityDate, today.plusDays(30)) + .le(BillLedger::getMaturityDate, today.plusDays(90)))); + counts.put("over90", count(Wrappers.lambdaQuery() + .gt(BillLedger::getMaturityDate, today.plusDays(90)))); + return counts; + } + + @Override + public List availableOptions(String keyword, Long deptId, Long selectedId) { + LocalDate today = LocalDate.now(); + return list(Wrappers.lambdaQuery() + .and(Func.isNotEmpty(keyword), wrapper -> wrapper.like(BillLedger::getBillNo, keyword) + .or().like(BillLedger::getIssuerName, keyword) + .or().like(BillLedger::getReceiverName, keyword)) + .and(wrapper -> wrapper + .gt(BillLedger::getAvailableBalance, BigDecimal.ZERO) + .ge(BillLedger::getMaturityDate, today) + .or(selectedId != null, child -> child.eq(BillLedger::getId, selectedId))) + .orderByAsc(BillLedger::getMaturityDate) + .orderByDesc(BillLedger::getCreateTime) + .last("limit 200")).stream() + .filter(item -> selectedId != null && Objects.equals(item.getId(), selectedId) + || departmentAvailable(item, deptId)) + .map(item -> BillLedgerWrapper.build().entityVO(item)) + .toList(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Long submit(BillLedgerSaveRequest request) { + validateRequest(request); + BillLedger entity = request.getId() == null ? new BillLedger() : locked(request.getId()); + String billNo = required(request.getBillNo(), "票据号码", 32); + if (entity.getId() != null && !billNo.equals(entity.getBillNo())) { + throw new ServiceException("票据号码编辑时不可修改"); + } + Long duplicate = count(Wrappers.lambdaQuery() + .eq(BillLedger::getBillNo, billNo) + .ne(entity.getId() != null, BillLedger::getId, entity.getId())); + if (duplicate > 0) { + throw new ServiceException("票据号码已存在"); + } + CustomerArchive issuer = customer(request.getIssuerId(), "出票单位"); + CustomerArchive feeBearer = customer(request.getFeeBearerId(), "费用承担方"); + BigDecimal faceAmount = positive(request.getFaceAmount(), "票面金额").setScale(2, RoundingMode.HALF_UP); + BigDecimal usedAmount = entity.getId() == null ? BigDecimal.ZERO : activeUsedAmount(entity.getId()); + if (faceAmount.compareTo(usedAmount) < 0) { + throw new ServiceException("票面金额不能小于已使用金额"); + } + + entity.setBillNo(billNo); + entity.setIssuerId(issuer.getId()); + entity.setIssuerName(customerName(issuer)); + entity.setReceiverName(required(request.getReceiverName(), "收票单位", 100)); + entity.setBillType(request.getBillType()); + entity.setFaceAmount(faceAmount); + entity.setAvailableBalance(faceAmount.subtract(usedAmount).setScale(2, RoundingMode.HALF_UP)); + entity.setIssueDate(request.getIssueDate()); + entity.setMaturityDate(request.getMaturityDate()); + entity.setAvailableDeptIdsJson(request.getAvailableDeptIdsJson()); + entity.setAvailableDeptNames(required(request.getAvailableDeptNames(), "可用部门", 500)); + entity.setFeeBearerId(feeBearer.getId()); + entity.setFeeBearerName(customerName(feeBearer)); + entity.setConfirmedDiscountRate(rate(request.getConfirmedDiscountRate(), "双方确认贴现率")); + entity.setIssuingBank(required(request.getIssuingBank(), "出票行", 100)); + entity.setBankDiscountReferenceRate(rate(request.getBankDiscountReferenceRate(), "银行贴现参考率")); + entity.setEstimatedDiscountFee(calculateDiscountFee(faceAmount, entity.getConfirmedDiscountRate())); + entity.setAttachmentsJson(request.getAttachmentsJson()); + entity.setRemark(limit(request.getRemark(), 200, "备注")); + if (entity.getId() == null) { + entity.setStatus(1); + } + saveOrUpdate(entity); + return entity.getId(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void removeLedger(Long id) { + BillLedger entity = locked(id); + if (usageMapper.selectCount(Wrappers.lambdaQuery() + .eq(BillLedgerUsage::getBillLedgerId, id) + .eq(BillLedgerUsage::getUsageStatus, APPROVED)) > 0) { + throw new ServiceException("存在已审核使用记录的汇票不允许删除"); + } + removeById(entity); + } + + private void validateRequest(BillLedgerSaveRequest request) { + if (request == null) { + throw new ServiceException("请求参数不能为空"); + } + if (!List.of("issued", "received").contains(request.getBillType())) { + throw new ServiceException("汇票类型不合法"); + } + if (request.getIssueDate() == null) { + throw new ServiceException("出票日期不能为空"); + } + if (request.getMaturityDate() == null || !request.getMaturityDate().isAfter(request.getIssueDate())) { + throw new ServiceException("到期日期必须晚于出票日期"); + } + List deptIds = parseArray(request.getAvailableDeptIdsJson(), "可用部门"); + if (deptIds.isEmpty()) { + throw new ServiceException("可用部门不能为空"); + } + } + + private void applyMaturityStatus(LambdaQueryWrapper wrapper, String status, + LocalDate today) { + if (Func.isEmpty(status)) return; + switch (status) { + case "expired" -> wrapper.lt(BillLedger::getMaturityDate, today); + case "due_today" -> wrapper.eq(BillLedger::getMaturityDate, today); + case "unexpired" -> wrapper.gt(BillLedger::getMaturityDate, today); + default -> throw new ServiceException("到期状态不合法"); + } + } + + private void applyExpiryShortcut(LambdaQueryWrapper wrapper, String shortcut, + LocalDate today) { + if (Func.isEmpty(shortcut) || "all".equals(shortcut)) return; + switch (shortcut) { + case "within30" -> wrapper.ge(BillLedger::getMaturityDate, today) + .le(BillLedger::getMaturityDate, today.plusDays(30)); + case "within90" -> wrapper.gt(BillLedger::getMaturityDate, today.plusDays(30)) + .le(BillLedger::getMaturityDate, today.plusDays(90)); + case "over90" -> wrapper.gt(BillLedger::getMaturityDate, today.plusDays(90)); + default -> throw new ServiceException("到期快捷筛选不合法"); + } + } + + private BillLedger existing(Long id) { + BillLedger entity = getById(id); + if (entity == null || Objects.equals(entity.getIsDeleted(), 1)) { + throw new ServiceException("汇票台账不存在"); + } + return entity; + } + + private BillLedger locked(Long id) { + BillLedger entity = baseMapper.selectOne(Wrappers.lambdaQuery() + .eq(BillLedger::getId, id).last("FOR UPDATE")); + if (entity == null || Objects.equals(entity.getIsDeleted(), 1)) { + throw new ServiceException("汇票台账不存在"); + } + return entity; + } + + private CustomerArchive customer(Long id, String name) { + if (id == null) throw new ServiceException(name + "不能为空"); + CustomerArchive customer = customerArchiveMapper.selectById(id); + if (customer == null || Objects.equals(customer.getIsDeleted(), 1)) { + throw new ServiceException(name + "对应的客商档案不存在"); + } + return customer; + } + + private BigDecimal activeUsedAmount(Long ledgerId) { + return usageMapper.selectList(Wrappers.lambdaQuery() + .eq(BillLedgerUsage::getBillLedgerId, ledgerId) + .eq(BillLedgerUsage::getUsageStatus, APPROVED)).stream() + .map(BillLedgerUsage::getUsedAmount) + .map(this::money) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + + private boolean departmentAvailable(BillLedger ledger, Long deptId) { + List values = parseArray(ledger.getAvailableDeptIdsJson(), "可用部门"); + if (values.stream().anyMatch(value -> "all".equals(String.valueOf(value)))) return true; + return deptId == null || values.stream().anyMatch(value -> String.valueOf(deptId).equals(String.valueOf(value))); + } + + private List parseArray(String value, String name) { + if (Func.isEmpty(value)) return List.of(); + try { + Object parsed = JsonUtil.parse(value, List.class); + return parsed instanceof List list ? list : List.of(); + } catch (Exception exception) { + throw new ServiceException(name + "格式不正确"); + } + } + + private String customerName(CustomerArchive customer) { + return Func.isNotEmpty(customer.getFullName()) ? customer.getFullName() : customer.getShortName(); + } + + private BigDecimal calculateDiscountFee(BigDecimal faceAmount, BigDecimal rate) { + if (rate == null) return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP); + return faceAmount.multiply(rate).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP); + } + + private BigDecimal positive(BigDecimal value, String name) { + if (value == null || value.compareTo(BigDecimal.ZERO) <= 0) { + throw new ServiceException(name + "必须大于0"); + } + if (value.scale() > 2) throw new ServiceException(name + "最多保留2位小数"); + return value; + } + + private BigDecimal rate(BigDecimal value, String name) { + if (value == null) return null; + if (value.compareTo(BigDecimal.ZERO) < 0 || value.compareTo(BigDecimal.valueOf(100)) > 0) { + throw new ServiceException(name + "必须在0-100之间"); + } + return value.setScale(Math.min(value.scale(), 4), RoundingMode.HALF_UP); + } + + private BigDecimal money(BigDecimal value) { + return value == null ? BigDecimal.ZERO : value; + } + + private String required(String value, String name, int length) { + if (Func.isEmpty(value) || value.trim().isEmpty()) throw new ServiceException(name + "不能为空"); + return limit(value.trim(), length, name); + } + + private String limit(String value, int length, String name) { + if (value != null && value.length() > length) { + throw new ServiceException(name + "不能超过" + length + "个字符"); + } + return value; + } +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/BillPaymentServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/BillPaymentServiceImpl.java new file mode 100644 index 0000000..15125ee --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/BillPaymentServiceImpl.java @@ -0,0 +1,343 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * Author: Chill Zhuang (bladejava@qq.com) + */ +package org.springblade.transport.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +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.jackson.JsonUtil; +import org.springblade.core.tool.utils.Func; +import org.springblade.system.cache.SysCache; +import org.springblade.transport.mapper.BillLedgerMapper; +import org.springblade.transport.mapper.BillLedgerUsageMapper; +import org.springblade.transport.mapper.BillPaymentMapper; +import org.springblade.transport.pojo.dto.BillPaymentSaveRequest; +import org.springblade.transport.pojo.dto.BillPaymentStatusRequest; +import org.springblade.transport.pojo.entity.BillLedger; +import org.springblade.transport.pojo.entity.BillLedgerUsage; +import org.springblade.transport.pojo.entity.BillPayment; +import org.springblade.transport.pojo.vo.BillPaymentVO; +import org.springblade.transport.service.IBillPaymentService; +import org.springblade.transport.wrapper.BillPaymentWrapper; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.Objects; + +/** 汇票付款服务实现。 @author Chill */ +@Service +@RequiredArgsConstructor +public class BillPaymentServiceImpl extends BaseServiceImpl + implements IBillPaymentService { + 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 static final String RELEASED = "released"; + + private final BillLedgerMapper billLedgerMapper; + private final BillLedgerUsageMapper usageMapper; + + @Override + public IPage selectPage(IPage page, BillPaymentVO query) { + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery() + .like(Func.isNotEmpty(query.getPaymentNo()), BillPayment::getPaymentNo, query.getPaymentNo()) + .like(Func.isNotEmpty(query.getDeptName()), BillPayment::getDeptName, query.getDeptName()) + .ge(query.getPaymentStartDate() != null, BillPayment::getPaymentDate, query.getPaymentStartDate()) + .le(query.getPaymentEndDate() != null, BillPayment::getPaymentDate, query.getPaymentEndDate()) + .eq(Func.isNotEmpty(query.getApprovalStatus()), BillPayment::getApprovalStatus, + query.getApprovalStatus()) + .orderByDesc(BillPayment::getCreateTime); + return page(page, wrapper).convert(item -> BillPaymentWrapper.build().entityVO(item)); + } + + @Override + public BillPaymentVO detail(Long id) { + BillPayment entity = existing(id); + BillPaymentVO vo = BillPaymentWrapper.build().entityVO(entity); + BillLedger ledger = billLedgerMapper.selectById(entity.getBillLedgerId()); + if (ledger != null) { + vo.setBillNo(ledger.getBillNo()); + vo.setFaceAmount(ledger.getFaceAmount()); + vo.setAvailableBalance(ledger.getAvailableBalance()); + } + return vo; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Long saveDraft(BillPaymentSaveRequest request) { + validateRequest(request); + BillPayment entity = request.getId() == null ? new BillPayment() : locked(request.getId()); + if (entity.getId() != null && !List.of(DRAFT, RETURNED).contains(entity.getApprovalStatus())) { + throw new ServiceException("当前状态不可编辑"); + } + Long deptId = Func.firstLong(AuthUtil.getDeptId()); + if (deptId == null) { + throw new ServiceException("使用部门不能为空"); + } + if (entity.getId() != null && !Objects.equals(entity.getDeptId(), deptId)) { + throw new ServiceException("仅允许编辑当前部门的汇票付款"); + } + String deptName = required(SysCache.getDeptName(deptId), "使用部门", 100); + BillLedger ledger = lockedBill(request.getBillLedgerId()); + BigDecimal usedAmount = positive(request.getUsedAmount(), "本次使用"); + validateLedgerAmount(ledger, usedAmount, deptId); + if (entity.getId() == null) { + entity.setPaymentNo(nextNo()); + entity.setApprovalStatus(DRAFT); + entity.setCurrentNode("草稿"); + } + entity.setBillLedgerId(ledger.getId()); + entity.setBillNo(ledger.getBillNo()); + entity.setFaceAmount(money(ledger.getFaceAmount()).setScale(2, RoundingMode.HALF_UP)); + entity.setAvailableBalance(money(ledger.getAvailableBalance()).setScale(2, RoundingMode.HALF_UP)); + entity.setUsedAmount(usedAmount); + entity.setDeptId(deptId); + entity.setDeptName(deptName); + entity.setPaymentDate(request.getPaymentDate() == null ? LocalDate.now() : request.getPaymentDate()); + entity.setAttachmentsJson(request.getAttachmentsJson()); + entity.setRemark(limit(request.getRemark(), 200, "备注")); + entity.setStatus(1); + saveOrUpdate(entity); + return entity.getId(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void removeDraft(Long id) { + BillPayment entity = locked(id); + if (!DRAFT.equals(entity.getApprovalStatus())) { + throw new ServiceException("仅草稿状态的汇票付款允许删除"); + } + removeById(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void submit(BillPaymentStatusRequest request) { + BillPayment entity = locked(requiredId(request)); + if (!List.of(DRAFT, RETURNED).contains(entity.getApprovalStatus())) { + throw new ServiceException("当前状态不允许提交"); + } + validateStoredAmount(entity); + entity.setApprovalStatus(REVIEWING); + entity.setCurrentNode("财务审核"); + entity.setCurrentProcessor(AuthUtil.getUserName()); + updateById(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void approve(BillPaymentStatusRequest request) { + BillPayment entity = locked(requiredId(request)); + if (!REVIEWING.equals(entity.getApprovalStatus())) { + throw new ServiceException("仅审批中的汇票付款允许审核"); + } + BillLedger ledger = lockedBill(entity.getBillLedgerId()); + validateLedgerAmount(ledger, entity.getUsedAmount(), entity.getDeptId()); + BillLedgerUsage exists = usageMapper.selectOne(Wrappers.lambdaQuery() + .eq(BillLedgerUsage::getBillPaymentId, entity.getId()) + .eq(BillLedgerUsage::getUsageStatus, APPROVED) + .last("FOR UPDATE")); + if (exists != null) { + throw new ServiceException("该汇票付款已生成使用记录"); + } + BigDecimal usedAmount = money(entity.getUsedAmount()).setScale(2, RoundingMode.HALF_UP); + ledger.setAvailableBalance(money(ledger.getAvailableBalance()).subtract(usedAmount) + .setScale(2, RoundingMode.HALF_UP)); + billLedgerMapper.updateById(ledger); + BillLedgerUsage usage = new BillLedgerUsage(); + usage.setBillLedgerId(ledger.getId()); + usage.setBillPaymentId(entity.getId()); + usage.setApplicationNo(entity.getPaymentNo()); + usage.setUsedAmount(usedAmount); + usage.setUseDeptId(entity.getDeptId()); + usage.setUseDeptName(entity.getDeptName()); + usage.setUsageStatus(APPROVED); + usage.setStatus(1); + usageMapper.insert(usage); + entity.setAvailableBalance(ledger.getAvailableBalance()); + entity.setApprovalStatus(APPROVED); + entity.setCurrentNode("审批通过"); + entity.setCurrentProcessor(AuthUtil.getUserName()); + updateById(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void returnBill(BillPaymentStatusRequest request) { + BillPayment entity = locked(requiredId(request)); + if (!REVIEWING.equals(entity.getApprovalStatus())) { + throw new ServiceException("仅审批中的汇票付款允许驳回"); + } + entity.setApprovalStatus(RETURNED); + entity.setCurrentNode("已驳回"); + entity.setCurrentProcessor(AuthUtil.getUserName()); + entity.setRemark(request.getReason() == null ? entity.getRemark() : limit(request.getReason(), 200, "驳回原因")); + updateById(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void voidBill(BillPaymentStatusRequest request) { + BillPayment entity = locked(requiredId(request)); + if (!APPROVED.equals(entity.getApprovalStatus())) { + throw new ServiceException("仅审批通过的汇票付款允许作废"); + } + BillLedgerUsage usage = usageMapper.selectOne(Wrappers.lambdaQuery() + .eq(BillLedgerUsage::getBillPaymentId, entity.getId()) + .eq(BillLedgerUsage::getUsageStatus, APPROVED) + .last("FOR UPDATE")); + if (usage == null) { + throw new ServiceException("未找到汇票使用记录,无法作废"); + } + BillLedger ledger = lockedBill(usage.getBillLedgerId()); + ledger.setAvailableBalance(money(ledger.getAvailableBalance()).add(money(usage.getUsedAmount())) + .min(money(ledger.getFaceAmount())).setScale(2, RoundingMode.HALF_UP)); + billLedgerMapper.updateById(ledger); + usage.setUsageStatus(RELEASED); + usageMapper.updateById(usage); + entity.setAvailableBalance(ledger.getAvailableBalance()); + entity.setApprovalStatus(VOIDED); + entity.setCurrentNode("已作废"); + entity.setCurrentProcessor(AuthUtil.getUserName()); + entity.setRemark(request.getReason() == null ? entity.getRemark() : limit(request.getReason(), 200, "作废原因")); + updateById(entity); + } + + private void validateRequest(BillPaymentSaveRequest request) { + if (request == null) throw new ServiceException("请求参数不能为空"); + if (request.getBillLedgerId() == null) throw new ServiceException("票据号码不能为空"); + if (request.getPaymentDate() == null) throw new ServiceException("付款日期不能为空"); + positive(request.getUsedAmount(), "本次使用"); + } + + private void validateStoredAmount(BillPayment entity) { + BillLedger ledger = lockedBill(entity.getBillLedgerId()); + validateLedgerAmount(ledger, entity.getUsedAmount(), entity.getDeptId()); + entity.setBillNo(ledger.getBillNo()); + entity.setFaceAmount(ledger.getFaceAmount()); + entity.setAvailableBalance(ledger.getAvailableBalance()); + } + + private void validateLedgerAmount(BillLedger ledger, BigDecimal usedAmount, Long deptId) { + if (ledger.getMaturityDate() != null && ledger.getMaturityDate().isBefore(LocalDate.now())) { + throw new ServiceException("所选汇票已到期"); + } + if (usedAmount == null || usedAmount.compareTo(BigDecimal.ZERO) <= 0) { + throw new ServiceException("本次使用必须大于0"); + } + if (usedAmount.scale() > 2) { + throw new ServiceException("本次使用最多保留2位小数"); + } + if (usedAmount.compareTo(money(ledger.getAvailableBalance())) > 0) { + throw new ServiceException("本次使用不能超过汇票可用余额"); + } + if (!departmentAvailable(ledger, deptId)) { + throw new ServiceException("当前使用部门不在汇票可用部门范围内"); + } + } + + private boolean departmentAvailable(BillLedger ledger, Long deptId) { + if (Func.isEmpty(ledger.getAvailableDeptIdsJson())) return false; + try { + Object parsed = JsonUtil.parse(ledger.getAvailableDeptIdsJson(), List.class); + if (!(parsed instanceof List values)) return false; + if (values.stream().anyMatch(item -> "all".equals(String.valueOf(item)))) return true; + return deptId != null && values.stream().anyMatch(item -> String.valueOf(deptId).equals(String.valueOf(item))); + } catch (Exception exception) { + throw new ServiceException("汇票可用部门配置不正确"); + } + } + + private BillLedger lockedBill(Long id) { + BillLedger ledger = billLedgerMapper.selectOne(Wrappers.lambdaQuery() + .eq(BillLedger::getId, id).last("FOR UPDATE")); + if (ledger == null || Objects.equals(ledger.getIsDeleted(), 1)) { + throw new ServiceException("所选汇票台账不存在"); + } + return ledger; + } + + private BillPayment locked(Long id) { + BillPayment entity = baseMapper.selectOne(Wrappers.lambdaQuery() + .eq(BillPayment::getId, id).last("FOR UPDATE")); + if (entity == null || Objects.equals(entity.getIsDeleted(), 1)) { + throw new ServiceException("汇票付款不存在"); + } + return entity; + } + + private BillPayment existing(Long id) { + BillPayment entity = getById(id); + if (entity == null || Objects.equals(entity.getIsDeleted(), 1)) { + throw new ServiceException("汇票付款不存在"); + } + return entity; + } + + private Long requiredId(BillPaymentStatusRequest request) { + if (request == null || request.getId() == null) throw new ServiceException("单据不能为空"); + return request.getId(); + } + + private synchronized String nextNo() { + String prefix = "HP" + LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE); + return prefix + String.format("%05d", count(Wrappers.lambdaQuery() + .likeRight(BillPayment::getPaymentNo, prefix)) + 1); + } + + private BigDecimal positive(BigDecimal value, String name) { + if (value == null || value.compareTo(BigDecimal.ZERO) <= 0) throw new ServiceException(name + "必须大于0"); + if (value.scale() > 2) throw new ServiceException(name + "最多保留2位小数"); + return value.setScale(2, RoundingMode.HALF_UP); + } + + private BigDecimal money(BigDecimal value) { + return value == null ? BigDecimal.ZERO : value; + } + + private String required(String value, String name, int length) { + if (Func.isEmpty(value) || value.trim().isEmpty()) throw new ServiceException(name + "不能为空"); + return limit(value.trim(), length, name); + } + + private String limit(String value, int length, String name) { + if (value != null && value.length() > length) throw new ServiceException(name + "不能超过" + length + "个字符"); + return value; + } +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/InvoiceApplicationServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/InvoiceApplicationServiceImpl.java new file mode 100644 index 0000000..63cb624 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/InvoiceApplicationServiceImpl.java @@ -0,0 +1,643 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * Author: Chill Zhuang (bladejava@qq.com) + */ +package org.springblade.transport.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +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.CustomerArchiveMapper; +import org.springblade.transport.mapper.CustomerContactMapper; +import org.springblade.transport.mapper.CustomerInvoiceInfoMapper; +import org.springblade.transport.mapper.FormalSettlementDetailMapper; +import org.springblade.transport.mapper.FormalSettlementMapper; +import org.springblade.transport.mapper.InvoiceApplicationDetailMapper; +import org.springblade.transport.mapper.InvoiceApplicationLineMapper; +import org.springblade.transport.mapper.InvoiceApplicationMapper; +import org.springblade.transport.mapper.InvoiceApplicationRecordMapper; +import org.springblade.transport.mapper.InvoiceApplicationSettlementMapper; +import org.springblade.transport.mapper.InvoiceApplicationSheetMapper; +import org.springblade.transport.pojo.dto.InvoiceApplicationSaveRequest; +import org.springblade.transport.pojo.dto.InvoiceApplicationStatusRequest; +import org.springblade.transport.pojo.entity.CustomerArchive; +import org.springblade.transport.pojo.entity.CustomerContact; +import org.springblade.transport.pojo.entity.CustomerInvoiceInfo; +import org.springblade.transport.pojo.entity.FormalSettlement; +import org.springblade.transport.pojo.entity.FormalSettlementDetail; +import org.springblade.transport.pojo.entity.InvoiceApplication; +import org.springblade.transport.pojo.entity.InvoiceApplicationDetail; +import org.springblade.transport.pojo.entity.InvoiceApplicationLine; +import org.springblade.transport.pojo.entity.InvoiceApplicationRecord; +import org.springblade.transport.pojo.entity.InvoiceApplicationSettlement; +import org.springblade.transport.pojo.entity.InvoiceApplicationSheet; +import org.springblade.transport.pojo.vo.InvoiceApplicationSheetVO; +import org.springblade.transport.pojo.vo.InvoiceApplicationVO; +import org.springblade.transport.service.IInvoiceApplicationService; +import org.springblade.transport.wrapper.InvoiceApplicationWrapper; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 开票申请服务实现类 + * + * @author Chill + */ +@Service +@RequiredArgsConstructor +public class InvoiceApplicationServiceImpl extends BaseServiceImpl + implements IInvoiceApplicationService { + 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 InvoiceApplicationSettlementMapper settlementRelationMapper; + private final InvoiceApplicationSheetMapper sheetMapper; + private final InvoiceApplicationLineMapper lineMapper; + private final InvoiceApplicationDetailMapper applicationDetailMapper; + private final InvoiceApplicationRecordMapper recordMapper; + private final FormalSettlementMapper formalSettlementMapper; + private final FormalSettlementDetailMapper formalSettlementDetailMapper; + private final CustomerArchiveMapper customerArchiveMapper; + private final CustomerInvoiceInfoMapper customerInvoiceInfoMapper; + private final CustomerContactMapper customerContactMapper; + + @Override + public IPage selectPage(IPage page, InvoiceApplicationVO query) { + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery() + .like(Func.isNotEmpty(query.getApplicationNo()), InvoiceApplication::getApplicationNo, query.getApplicationNo()) + .like(Func.isNotEmpty(query.getProjectName()), InvoiceApplication::getProjectName, query.getProjectName()) + .like(Func.isNotEmpty(query.getDeptName()), InvoiceApplication::getDeptName, query.getDeptName()) + .eq(Func.isNotEmpty(query.getKingdeeStatus()), InvoiceApplication::getKingdeeStatus, query.getKingdeeStatus()) + .eq(Func.isNotEmpty(query.getApprovalStatus()), InvoiceApplication::getApprovalStatus, query.getApprovalStatus()) + .orderByDesc(InvoiceApplication::getCreateTime); + return page(page, wrapper).convert(this::toListVO); + } + + @Override + public InvoiceApplicationVO detail(Long id) { + InvoiceApplication entity = existing(id); + InvoiceApplicationVO vo = toListVO(entity); + vo.setSettlements(settlementRelationMapper.selectList(Wrappers.lambdaQuery() + .eq(InvoiceApplicationSettlement::getInvoiceApplicationId, id) + .orderByAsc(InvoiceApplicationSettlement::getCreateTime))); + List sheets = sheetMapper.selectList(Wrappers.lambdaQuery() + .eq(InvoiceApplicationSheet::getInvoiceApplicationId, id).orderByAsc(InvoiceApplicationSheet::getSheetNo)); + vo.setSheets(sheets.stream().map(sheet -> { + InvoiceApplicationSheetVO sheetVO = Objects.requireNonNull(BeanUtil.copyProperties(sheet, InvoiceApplicationSheetVO.class)); + sheetVO.setLines(lineMapper.selectList(Wrappers.lambdaQuery() + .eq(InvoiceApplicationLine::getInvoiceSheetId, sheet.getId()).orderByAsc(InvoiceApplicationLine::getLineNo))); + return sheetVO; + }).toList()); + vo.setDetails(applicationDetailMapper.selectList(Wrappers.lambdaQuery() + .eq(InvoiceApplicationDetail::getInvoiceApplicationId, id).orderByAsc(InvoiceApplicationDetail::getLineNo))); + vo.setRecords(recordMapper.selectList(Wrappers.lambdaQuery() + .eq(InvoiceApplicationRecord::getInvoiceApplicationId, id) + .orderByAsc(InvoiceApplicationRecord::getCreateTime))); + return vo; + } + + @Override + public List> settlementCandidates(String keyword) { + List settlements = formalSettlementMapper.selectList(Wrappers.lambdaQuery() + .eq(FormalSettlement::getSettlementType, "receivable") + .eq(FormalSettlement::getApprovalStatus, APPROVED) + .eq(FormalSettlement::getStatus, 1) + .and(Func.isNotEmpty(keyword), wrapper -> wrapper.like(FormalSettlement::getFormalSettlementNo, keyword) + .or().like(FormalSettlement::getProjectName, keyword) + .or().like(FormalSettlement::getContractName, keyword)) + .orderByDesc(FormalSettlement::getCreateTime).last("limit 200")); + return settlements.stream().map(settlement -> { + BigDecimal available = availableAmount(settlement, null); + Map row = new LinkedHashMap<>(); + row.put("id", settlement.getId()); + row.put("formalSettlementNo", settlement.getFormalSettlementNo()); + row.put("projectId", settlement.getProjectId()); + row.put("projectName", settlement.getProjectName()); + row.put("deptId", settlement.getDeptId()); + row.put("deptName", settlement.getDeptName()); + row.put("contractId", settlement.getContractId()); + row.put("contractNo", settlement.getContractNo()); + row.put("contractName", settlement.getContractName()); + row.put("issuerName", settlement.getPayeeName()); + row.put("receiverName", settlement.getPayerName()); + row.put("settlementAmount", money(settlement.getSettlementAmount())); + row.put("availableInvoiceAmount", available); + return row; + }).filter(row -> ((BigDecimal) row.get("availableInvoiceAmount")).compareTo(BigDecimal.ZERO) > 0).toList(); + } + + @Override + public List settlementDetails(String settlementIds) { + List ids = distinctIds(settlementIds); + if (ids.isEmpty()) return List.of(); + assertCompatible(ids.stream().map(this::availableSettlement).toList()); + return formalSettlementDetailMapper.selectList(Wrappers.lambdaQuery() + .in(FormalSettlementDetail::getFormalSettlementId, ids).orderByAsc(FormalSettlementDetail::getLineNo)); + } + + @Override + public Map receiverInformation(String settlementIds) { + List settlements = distinctIds(settlementIds).stream().map(this::availableSettlement).toList(); + assertCompatible(settlements); + FormalSettlement first = settlements.get(0); + CustomerArchive customer = findCustomer(first.getPayerName()); + Map result = new LinkedHashMap<>(); + result.put("issuerName", first.getPayeeName()); + result.put("receiverName", first.getPayerName()); + result.put("customer", customer); + result.put("invoiceInfos", customer == null ? List.of() : customerInvoiceInfoMapper.selectList( + Wrappers.lambdaQuery().eq(CustomerInvoiceInfo::getCustomerId, customer.getId()) + .eq(CustomerInvoiceInfo::getStatus, 1).orderByDesc(CustomerInvoiceInfo::getIsDefault))); + result.put("contacts", customer == null ? List.of() : customerContactMapper.selectList( + Wrappers.lambdaQuery().eq(CustomerContact::getCustomerId, customer.getId()) + .eq(CustomerContact::getStatus, 1).orderByDesc(CustomerContact::getIsDefault))); + return result; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Long saveDraft(InvoiceApplicationSaveRequest request) { + validateRequest(request); + boolean creating = request.getId() == null; + InvoiceApplication entity = creating ? new InvoiceApplication() : editable(request.getId()); + List oldSettlementIds = entity.getId() == null ? List.of() : relationSettlementIds(entity.getId()); + List requestedRows = request.getSettlements().stream() + .filter(Objects::nonNull) + .peek(row -> { + if (row.getSettlementId() == null) throw new ServiceException("正式结算单不能为空"); + }) + .collect(Collectors.toMap(InvoiceApplicationSaveRequest.SettlementRow::getSettlementId, + Function.identity(), (first, duplicate) -> first, LinkedHashMap::new)).values().stream().toList(); + List settlements = requestedRows.stream().map(row -> availableSettlement(row.getSettlementId())).toList(); + assertCompatible(settlements); + FormalSettlement first = settlements.get(0); + Map settlementMap = settlements.stream() + .collect(Collectors.toMap(FormalSettlement::getId, Function.identity())); + BigDecimal totalAvailable = BigDecimal.ZERO; + BigDecimal allocatedTotal = BigDecimal.ZERO; + for (InvoiceApplicationSaveRequest.SettlementRow row : requestedRows) { + FormalSettlement settlement = settlementMap.get(row.getSettlementId()); + BigDecimal available = availableAmount(settlement, entity.getId()); + BigDecimal allocated = nonNegative(row.getAllocatedInvoiceAmount(), "分摊发票金额"); + if (allocated.compareTo(available) > 0) { + throw new ServiceException("结算单" + settlement.getFormalSettlementNo() + "的分摊金额超过剩余可开票金额"); + } + totalAvailable = totalAvailable.add(available); + allocatedTotal = allocatedTotal.add(allocated); + } + BigDecimal lineTotal = validateSheets(request.getSheets()); + if (lineTotal.compareTo(BigDecimal.ZERO) <= 0) { + throw new ServiceException("本次开票金额必须大于0"); + } + if (lineTotal.compareTo(allocatedTotal) != 0) { + throw new ServiceException("开票商品行金额合计必须等于结算单分摊金额合计"); + } + CustomerArchive customer = findCustomer(first.getPayerName()); + CustomerInvoiceInfo invoiceInfo = customerInvoiceInfoMapper.selectById(request.getReceiverInvoiceInfoId()); + if (customer == null || invoiceInfo == null || !Objects.equals(customer.getId(), invoiceInfo.getCustomerId()) + || Objects.equals(invoiceInfo.getIsDeleted(), 1) || !Objects.equals(invoiceInfo.getStatus(), 1)) { + throw new ServiceException("请选择受票方有效的开票信息"); + } + String invoiceTitle = required(invoiceInfo.getInvoiceTitle(), "受票方单位"); + String taxpayerNo = limit(invoiceInfo.getTaxNo(), 20, "纳税人识别号"); + String bankName = limit(invoiceInfo.getBankName(), 100, "开户行"); + String bankAccount = limit(invoiceInfo.getBankAccount(), 50, "开户账号"); + String registeredAddress = limit(invoiceInfo.getRegisteredAddress(), 200, "注册地址"); + if ("electronic_special".equals(request.getInvoiceType())) { + required(taxpayerNo, "电子专票的纳税人识别号"); + required(bankName, "电子专票的开户行"); + required(bankAccount, "电子专票的开户账号"); + required(registeredAddress, "电子专票的注册地址"); + } + if (entity.getId() == null) { + entity.setApplicationNo(nextNo()); + entity.setApprovalStatus(DRAFT); + entity.setCurrentNode("草稿"); + entity.setKingdeeStatus("unsynced"); + entity.setApplicantName(AuthUtil.getUserName()); + } + entity.setProjectId(first.getProjectId()); + entity.setProjectName(first.getProjectName()); + entity.setDeptId(first.getDeptId()); + entity.setDeptName(first.getDeptName()); + entity.setIssuerName(first.getPayeeName()); + entity.setReceiverCustomerId(customer.getId()); + entity.setReceiverName(invoiceTitle); + entity.setInvoiceType(request.getInvoiceType()); + entity.setAvailableInvoiceAmount(totalAvailable); + entity.setInvoiceAmount(lineTotal); + entity.setUndertakingDeptId(first.getDeptId()); + entity.setUndertakingDeptName(first.getDeptName()); + entity.setDepartmentEmails(normalizeEmails(request.getDepartmentEmails())); + entity.setReceiverInvoiceInfoId(invoiceInfo.getId()); + entity.setTaxpayerNo(taxpayerNo); + entity.setBankName(bankName); + entity.setBankAccount(bankAccount); + entity.setRegisteredAddress(registeredAddress); + entity.setContactName(limit(request.getContactName(), 50, "联系人")); + entity.setContactPhone(validatePhone(request.getContactPhone())); + entity.setEmail(validateReceiverEmails(request.getEmail())); + entity.setAttachmentsJson(request.getAttachmentsJson()); + entity.setRemark(limit(request.getRemark(), 200, "备注")); + saveOrUpdate(entity); + deleteChildren(entity.getId()); + saveRelations(entity.getId(), requestedRows, settlementMap); + saveSheets(entity.getId(), request.getSheets()); + saveDetails(entity.getId(), request.getDetailIds(), settlementMap.keySet()); + Set refreshIds = new LinkedHashSet<>(oldSettlementIds); + refreshIds.addAll(settlementMap.keySet()); + refreshIds.forEach(this::refreshSettlementInvoiceStatus); + record(entity.getId(), creating ? "create" : "save", creating ? "创建草稿" : "保存草稿", + entity.getApprovalStatus(), entity.getApprovalStatus(), null, null); + return entity.getId(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void removeDraft(Long id) { + InvoiceApplication entity = editable(id); + List settlementIds = relationSettlementIds(id); + deleteChildren(id); + removeById(entity); + settlementIds.forEach(this::refreshSettlementInvoiceStatus); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void submit(InvoiceApplicationStatusRequest request) { + InvoiceApplication entity = editable(request.getId()); + String fromStatus = entity.getApprovalStatus(); + entity.setApprovalStatus(REVIEWING); + entity.setCurrentNode("开票审核"); + entity.setCurrentProcessor(null); + entity.setApplicationDate(LocalDate.now()); + updateById(entity); + record(entity.getId(), "submit", "提交审批", fromStatus, REVIEWING, null, null); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void approve(InvoiceApplicationStatusRequest request) { + changeStatus(request.getId(), REVIEWING, APPROVED, "approve", "审批通过", null); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void returnBill(InvoiceApplicationStatusRequest request) { + changeStatus(request.getId(), REVIEWING, RETURNED, "return", "已驳回", + required(request.getReason(), "驳回原因")); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void voidBill(InvoiceApplicationStatusRequest request) { + InvoiceApplication entity = existing(request.getId()); + if (!APPROVED.equals(entity.getApprovalStatus())) throw new ServiceException("仅审批通过的开票申请允许作废"); + entity.setApprovalStatus(VOIDED); + entity.setCurrentNode("已作废"); + entity.setCurrentProcessor(AuthUtil.getUserName()); + entity.setVoidReason(limit(required(request.getReason(), "作废原因"), 200, "作废原因")); + updateById(entity); + record(entity.getId(), "void", "作废", APPROVED, VOIDED, entity.getVoidReason(), entity.getKingdeeBillNo()); + relationSettlementIds(entity.getId()).forEach(this::refreshSettlementInvoiceStatus); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public String syncKingdee(Long id) { + InvoiceApplication entity = existing(id); + if (!APPROVED.equals(entity.getApprovalStatus())) throw new ServiceException("仅审批通过的开票申请允许同步金蝶"); + if ("synced".equals(entity.getKingdeeStatus())) return entity.getKingdeeBillNo(); + String kingdeeNo = "K3INV" + DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now()); + entity.setKingdeeBillNo(kingdeeNo); + entity.setKingdeeStatus("synced"); + entity.setSyncedTime(LocalDateTime.now()); + updateById(entity); + record(entity.getId(), "sync", "同步金蝶", entity.getApprovalStatus(), entity.getApprovalStatus(), null, kingdeeNo); + return kingdeeNo; + } + + private InvoiceApplicationVO toListVO(InvoiceApplication entity) { + InvoiceApplicationVO vo = InvoiceApplicationWrapper.build().entityVO(entity); + vo.setSettlementNos(settlementRelationMapper.selectList(Wrappers.lambdaQuery() + .eq(InvoiceApplicationSettlement::getInvoiceApplicationId, entity.getId()) + .orderByAsc(InvoiceApplicationSettlement::getCreateTime)).stream() + .map(InvoiceApplicationSettlement::getFormalSettlementNo).collect(Collectors.joining(","))); + return vo; + } + + private void validateRequest(InvoiceApplicationSaveRequest request) { + if (request.getSettlements() == null || request.getSettlements().isEmpty()) throw new ServiceException("请至少选择一张正式结算单"); + if (request.getDetailIds() == null || request.getDetailIds().isEmpty()) throw new ServiceException("请至少选择一条开票明细"); + if (!List.of("electronic_special", "electronic_normal").contains(request.getInvoiceType())) throw new ServiceException("请选择有效的发票类型"); + if (request.getReceiverInvoiceInfoId() == null) throw new ServiceException("请选择受票方单位"); + if (Func.isEmpty(request.getDepartmentEmails())) throw new ServiceException("请选择部门邮箱"); + } + + private BigDecimal validateSheets(List sheets) { + if (sheets == null || sheets.isEmpty()) throw new ServiceException("请至少添加一张发票"); + BigDecimal total = BigDecimal.ZERO; + for (InvoiceApplicationSaveRequest.SheetRow sheet : sheets) { + if (sheet.getLines() == null || sheet.getLines().isEmpty()) throw new ServiceException("每张发票至少需要一条商品行"); + boolean containsFreight = sheet.getLines().stream().anyMatch(line -> "运费".equals(line.getGoodsName())); + boolean containsOther = sheet.getLines().stream().anyMatch(line -> !"运费".equals(line.getGoodsName())); + if (containsFreight && containsOther) throw new ServiceException("运费不能与其他费用合并开在同一张发票中"); + for (InvoiceApplicationSaveRequest.LineRow line : sheet.getLines()) { + required(line.getGoodsCategory(), "商品和服务分类"); + required(line.getGoodsName(), "货物或服务简称"); + nonNegative(line.getQuantity(), "数量"); + nonNegative(line.getUnitPriceNoTax(), "不含税单价"); + BigDecimal amount = nonNegative(line.getAmountWithTax(), "含税金额"); + BigDecimal taxRate = nonNegative(line.getTaxRate(), "税率"); + if (taxRate.compareTo(BigDecimal.valueOf(100)) > 0) throw new ServiceException("税率必须在0-100之间"); + line.setTaxAmount(calculateTax(amount, taxRate)); + line.setRemark(limit(line.getRemark(), 200, "商品行备注")); + total = total.add(amount); + } + } + return total.setScale(2, RoundingMode.HALF_UP); + } + + private void assertCompatible(List settlements) { + if (settlements.isEmpty()) throw new ServiceException("请选择正式结算单"); + FormalSettlement first = settlements.get(0); + if (settlements.stream().anyMatch(item -> !Objects.equals(first.getContractId(), item.getContractId()) + || !Objects.equals(first.getProjectId(), item.getProjectId()) + || !Objects.equals(first.getDeptId(), item.getDeptId()) + || !Objects.equals(first.getPayerName(), item.getPayerName()) + || !Objects.equals(first.getPayeeName(), item.getPayeeName()))) { + throw new ServiceException("合并开票的正式结算单必须属于同一合同、项目、组织及收付款方"); + } + } + + private FormalSettlement availableSettlement(Long id) { + if (id == null) throw new ServiceException("正式结算单不能为空"); + FormalSettlement settlement = formalSettlementMapper.selectById(id); + if (settlement == null || Objects.equals(settlement.getIsDeleted(), 1)) throw new ServiceException("正式结算单不存在"); + if (!Objects.equals(settlement.getStatus(), 1) || !APPROVED.equals(settlement.getApprovalStatus()) + || !"receivable".equals(settlement.getSettlementType())) { + throw new ServiceException("只能选择审批通过、未作废的应收正式结算单"); + } + return settlement; + } + + private BigDecimal availableAmount(FormalSettlement settlement, Long excludeApplicationId) { + BigDecimal allocated = activeRelations(settlement.getId(), excludeApplicationId).stream() + .map(InvoiceApplicationSettlement::getAllocatedInvoiceAmount).map(this::money) + .reduce(BigDecimal.ZERO, BigDecimal::add); + return money(settlement.getSettlementAmount()).subtract(allocated).max(BigDecimal.ZERO); + } + + private List activeRelations(Long settlementId, Long excludeApplicationId) { + List relations = settlementRelationMapper.selectList( + Wrappers.lambdaQuery() + .eq(InvoiceApplicationSettlement::getFormalSettlementId, settlementId) + .ne(excludeApplicationId != null, InvoiceApplicationSettlement::getInvoiceApplicationId, excludeApplicationId)); + if (relations.isEmpty()) return List.of(); + Map applications = listByIds(relations.stream() + .map(InvoiceApplicationSettlement::getInvoiceApplicationId).distinct().toList()).stream() + .collect(Collectors.toMap(InvoiceApplication::getId, Function.identity())); + return relations.stream().filter(relation -> { + InvoiceApplication application = applications.get(relation.getInvoiceApplicationId()); + return application != null && !VOIDED.equals(application.getApprovalStatus()) + && !Objects.equals(application.getIsDeleted(), 1); + }).toList(); + } + + private void saveRelations(Long applicationId, List rows, + Map settlementMap) { + for (InvoiceApplicationSaveRequest.SettlementRow row : rows) { + FormalSettlement source = settlementMap.get(row.getSettlementId()); + InvoiceApplicationSettlement relation = new InvoiceApplicationSettlement(); + relation.setInvoiceApplicationId(applicationId); + relation.setFormalSettlementId(source.getId()); + relation.setFormalSettlementNo(source.getFormalSettlementNo()); + relation.setSettlementAmount(source.getSettlementAmount()); + relation.setAvailableInvoiceAmount(availableAmount(source, applicationId)); + relation.setAllocatedInvoiceAmount(row.getAllocatedInvoiceAmount()); + settlementRelationMapper.insert(relation); + } + } + + private void saveSheets(Long applicationId, List sheets) { + int sheetNo = 1; + for (InvoiceApplicationSaveRequest.SheetRow sheetRow : sheets) { + InvoiceApplicationSheet sheet = new InvoiceApplicationSheet(); + sheet.setInvoiceApplicationId(applicationId); + sheet.setSheetNo(sheetNo++); + sheet.setInvoiceAmount(sheetRow.getLines().stream().map(InvoiceApplicationSaveRequest.LineRow::getAmountWithTax) + .map(this::money).reduce(BigDecimal.ZERO, BigDecimal::add)); + sheetMapper.insert(sheet); + int lineNo = 1; + for (InvoiceApplicationSaveRequest.LineRow lineRow : sheetRow.getLines()) { + InvoiceApplicationLine line = Objects.requireNonNull(BeanUtil.copyProperties(lineRow, InvoiceApplicationLine.class)); + line.setId(null); + line.setInvoiceApplicationId(applicationId); + line.setInvoiceSheetId(sheet.getId()); + line.setLineNo(lineNo++); + lineMapper.insert(line); + } + } + } + + private void saveDetails(Long applicationId, List detailIds, Set settlementIds) { + List details = formalSettlementDetailMapper.selectBatchIds(detailIds.stream().distinct().toList()); + if (details.size() != detailIds.stream().distinct().count() + || details.stream().anyMatch(detail -> !settlementIds.contains(detail.getFormalSettlementId()))) { + throw new ServiceException("开票明细必须来自已选择的正式结算单"); + } + int lineNo = 1; + for (FormalSettlementDetail source : details) { + InvoiceApplicationDetail detail = Objects.requireNonNull(BeanUtil.copyProperties(source, InvoiceApplicationDetail.class)); + detail.setId(null); + detail.setInvoiceApplicationId(applicationId); + detail.setFormalSettlementDetailId(source.getId()); + detail.setLineNo(lineNo++); + applicationDetailMapper.insert(detail); + } + } + + private void deleteChildren(Long applicationId) { + List sheetIds = sheetMapper.selectList(Wrappers.lambdaQuery() + .eq(InvoiceApplicationSheet::getInvoiceApplicationId, applicationId)).stream() + .map(InvoiceApplicationSheet::getId).toList(); + if (!sheetIds.isEmpty()) lineMapper.delete(Wrappers.lambdaQuery() + .in(InvoiceApplicationLine::getInvoiceSheetId, sheetIds)); + sheetMapper.delete(Wrappers.lambdaQuery() + .eq(InvoiceApplicationSheet::getInvoiceApplicationId, applicationId)); + applicationDetailMapper.delete(Wrappers.lambdaQuery() + .eq(InvoiceApplicationDetail::getInvoiceApplicationId, applicationId)); + settlementRelationMapper.delete(Wrappers.lambdaQuery() + .eq(InvoiceApplicationSettlement::getInvoiceApplicationId, applicationId)); + } + + private void refreshSettlementInvoiceStatus(Long settlementId) { + FormalSettlement settlement = formalSettlementMapper.selectById(settlementId); + if (settlement == null) return; + BigDecimal allocated = activeRelations(settlementId, null).stream() + .map(InvoiceApplicationSettlement::getAllocatedInvoiceAmount).map(this::money) + .reduce(BigDecimal.ZERO, BigDecimal::add); + String status = allocated.compareTo(BigDecimal.ZERO) <= 0 ? "unreceived" + : allocated.compareTo(money(settlement.getSettlementAmount())) >= 0 ? "completed" : "partial"; + settlement.setInvoiceStatus(status); + formalSettlementMapper.updateById(settlement); + } + + private List relationSettlementIds(Long applicationId) { + return settlementRelationMapper.selectList(Wrappers.lambdaQuery() + .eq(InvoiceApplicationSettlement::getInvoiceApplicationId, applicationId)).stream() + .map(InvoiceApplicationSettlement::getFormalSettlementId).distinct().toList(); + } + + private CustomerArchive findCustomer(String name) { + if (Func.isEmpty(name)) return null; + return customerArchiveMapper.selectOne(Wrappers.lambdaQuery() + .and(wrapper -> wrapper.eq(CustomerArchive::getFullName, name).or().eq(CustomerArchive::getShortName, name)) + .eq(CustomerArchive::getStatus, 1) + .eq(CustomerArchive::getIsDeleted, 0).last("limit 1")); + } + + private void changeStatus(Long id, String from, String to, String actionType, String node, String reason) { + InvoiceApplication entity = existing(id); + if (!from.equals(entity.getApprovalStatus())) throw new ServiceException("当前状态不允许此操作"); + entity.setApprovalStatus(to); + entity.setCurrentNode(node); + entity.setCurrentProcessor(AuthUtil.getUserName()); + updateById(entity); + record(id, actionType, node, from, to, reason, entity.getKingdeeBillNo()); + } + + private void record(Long applicationId, String actionType, String actionName, String fromStatus, + String toStatus, String reason, String kingdeeBillNo) { + InvoiceApplicationRecord record = new InvoiceApplicationRecord(); + record.setInvoiceApplicationId(applicationId); + record.setActionType(actionType); + record.setActionName(actionName); + record.setFromStatus(fromStatus); + record.setToStatus(toStatus); + record.setOperatorName(AuthUtil.getUserName()); + record.setReason(reason); + record.setKingdeeBillNo(kingdeeBillNo); + recordMapper.insert(record); + } + + private InvoiceApplication existing(Long id) { + InvoiceApplication entity = getById(id); + if (entity == null || Objects.equals(entity.getIsDeleted(), 1)) throw new ServiceException("开票申请不存在"); + return entity; + } + + private InvoiceApplication editable(Long id) { + InvoiceApplication entity = existing(id); + if (!List.of(DRAFT, RETURNED).contains(entity.getApprovalStatus())) throw new ServiceException("当前状态不可编辑"); + return entity; + } + + private List distinctIds(String ids) { + return ids == null ? List.of() : Func.toLongList(ids).stream().distinct().toList(); + } + + private String nextNo() { + String prefix = "KP-" + LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE); + return prefix + String.format("%05d", count(Wrappers.lambdaQuery() + .likeRight(InvoiceApplication::getApplicationNo, prefix)) + 1); + } + + private String normalizeEmails(String value) { + List emails = value == null ? List.of() : List.of(value.split("[;,,;]")); + List normalized = emails.stream().map(String::trim).filter(item -> !item.isEmpty()).distinct().toList(); + if (normalized.isEmpty() || normalized.size() > 3) throw new ServiceException("部门邮箱必填且最多选择3个"); + normalized.forEach(email -> validateEmail(email, "部门邮箱")); + return String.join(";", normalized); + } + + private String validateEmail(String value, String name) { + String result = limit(value, 100, name); + if (Func.isNotEmpty(result) && !result.matches("^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$")) { + throw new ServiceException(name + "格式不正确"); + } + return result; + } + + private String validateReceiverEmails(String value) { + if (Func.isEmpty(value)) return value; + List emails = List.of(value.split("[;,,;]")).stream() + .map(String::trim).filter(item -> !item.isEmpty()).distinct().toList(); + if (emails.size() > 3) throw new ServiceException("邮箱最多填写3个"); + emails.forEach(email -> validateEmail(email, "邮箱")); + return limit(String.join(";", emails), 100, "邮箱"); + } + + private String validatePhone(String value) { + if (Func.isNotEmpty(value) && !value.matches("^\\d{11}$")) throw new ServiceException("联系电话必须为11位数字"); + return value; + } + + private BigDecimal calculateTax(BigDecimal amount, BigDecimal rate) { + if (rate.compareTo(BigDecimal.ZERO) == 0) return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP); + return amount.subtract(amount.divide(BigDecimal.ONE.add(rate.divide(BigDecimal.valueOf(100), 8, + RoundingMode.HALF_UP)), 8, RoundingMode.HALF_UP)).setScale(2, RoundingMode.HALF_UP); + } + + private BigDecimal nonNegative(BigDecimal value, String name) { + if (value == null || value.compareTo(BigDecimal.ZERO) < 0) throw new ServiceException(name + "不能小于0"); + return value; + } + + private BigDecimal money(BigDecimal value) { + return value == null ? BigDecimal.ZERO : value; + } + + private String required(String value, String name) { + if (Func.isEmpty(value)) throw new ServiceException(name + "不能为空"); + return value; + } + + private String limit(String value, int length, String name) { + if (value != null && value.length() > length) throw new ServiceException(name + "不能超过" + length + "个字符"); + return value; + } +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/InvoiceReceiptServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/InvoiceReceiptServiceImpl.java new file mode 100644 index 0000000..2d7e310 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/InvoiceReceiptServiceImpl.java @@ -0,0 +1,684 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * Author: Chill Zhuang (bladejava@qq.com) + */ +package org.springblade.transport.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +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.Func; +import org.springblade.transport.mapper.CustomerArchiveMapper; +import org.springblade.transport.mapper.CustomerContactMapper; +import org.springblade.transport.mapper.FormalSettlementMapper; +import org.springblade.transport.mapper.InvoiceReceiptMapper; +import org.springblade.transport.mapper.InvoiceReceiptRecordMapper; +import org.springblade.transport.mapper.InvoiceReceiptSettlementMapper; +import org.springblade.transport.mapper.KingdeeInvoicePoolMapper; +import org.springblade.transport.pojo.dto.InvoiceReceiptSaveRequest; +import org.springblade.transport.pojo.dto.InvoiceReceiptStatusRequest; +import org.springblade.transport.pojo.entity.CustomerArchive; +import org.springblade.transport.pojo.entity.CustomerContact; +import org.springblade.transport.pojo.entity.FormalSettlement; +import org.springblade.transport.pojo.entity.InvoiceReceipt; +import org.springblade.transport.pojo.entity.InvoiceReceiptRecord; +import org.springblade.transport.pojo.entity.InvoiceReceiptSettlement; +import org.springblade.transport.pojo.entity.KingdeeInvoicePool; +import org.springblade.transport.pojo.vo.InvoiceReceiptVO; +import org.springblade.transport.service.IInvoiceReceiptService; +import org.springblade.transport.wrapper.InvoiceReceiptWrapper; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 收票登记服务实现类 + * + * @author Chill + */ +@Service +@RequiredArgsConstructor +public class InvoiceReceiptServiceImpl extends BaseServiceImpl + implements IInvoiceReceiptService { + + 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 KingdeeInvoicePoolMapper invoicePoolMapper; + private final InvoiceReceiptSettlementMapper settlementRelationMapper; + private final InvoiceReceiptRecordMapper recordMapper; + private final FormalSettlementMapper formalSettlementMapper; + private final CustomerArchiveMapper customerArchiveMapper; + private final CustomerContactMapper customerContactMapper; + + @Override + public IPage selectPage(IPage page, InvoiceReceiptVO query) { + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery() + .like(Func.isNotEmpty(query.getInvoiceNo()), InvoiceReceipt::getInvoiceNo, query.getInvoiceNo()) + .eq(query.getInvoiceDate() != null, InvoiceReceipt::getInvoiceDate, query.getInvoiceDate()) + .like(Func.isNotEmpty(query.getProjectName()), InvoiceReceipt::getProjectName, query.getProjectName()) + .like(Func.isNotEmpty(query.getDeptName()), InvoiceReceipt::getDeptName, query.getDeptName()) + .eq(Func.isNotEmpty(query.getApprovalStatus()), InvoiceReceipt::getApprovalStatus, + query.getApprovalStatus()) + .eq(Func.isNotEmpty(query.getKingdeeStatus()), InvoiceReceipt::getKingdeeStatus, + query.getKingdeeStatus()) + .orderByDesc(InvoiceReceipt::getCreateTime); + return page(page, wrapper).convert(this::toListVO); + } + + @Override + public InvoiceReceiptVO detail(Long id) { + InvoiceReceipt entity = existing(id); + InvoiceReceiptVO vo = toListVO(entity); + List settlements = settlementRelationMapper.selectList( + Wrappers.lambdaQuery() + .eq(InvoiceReceiptSettlement::getInvoiceReceiptId, id) + .orderByAsc(InvoiceReceiptSettlement::getCreateTime)); + settlements.forEach(item -> { + FormalSettlement source = formalSettlementMapper.selectById(item.getFormalSettlementId()); + if (source != null) { + item.setSettlementAmount(money(source.getSettlementAmount())); + } + item.setReceivedInvoiceAmount(receivedAmount(item.getFormalSettlementId(), id)); + }); + vo.setSettlements(settlements); + vo.setRecords(recordMapper.selectList(Wrappers.lambdaQuery() + .eq(InvoiceReceiptRecord::getInvoiceReceiptId, id) + .orderByAsc(InvoiceReceiptRecord::getCreateTime))); + return vo; + } + + @Override + public List invoicePool(String keyword) { + return invoicePoolMapper.selectList(Wrappers.lambdaQuery() + .eq(KingdeeInvoicePool::getStatus, 1) + .and(Func.isNotEmpty(keyword), wrapper -> wrapper.like(KingdeeInvoicePool::getInvoiceNo, keyword) + .or().like(KingdeeInvoicePool::getIssuerName, keyword) + .or().like(KingdeeInvoicePool::getReceiverName, keyword)) + .orderByDesc(KingdeeInvoicePool::getSourceUpdatedTime) + .orderByDesc(KingdeeInvoicePool::getCreateTime) + .last("limit 200")); + } + + @Override + public List> settlementCandidates(String keyword, Long receiptId) { + List settlements = formalSettlementMapper.selectList( + Wrappers.lambdaQuery() + .eq(FormalSettlement::getSettlementType, "payable") + .eq(FormalSettlement::getApprovalStatus, APPROVED) + .eq(FormalSettlement::getStatus, 1) + .and(Func.isNotEmpty(keyword), wrapper -> wrapper + .like(FormalSettlement::getFormalSettlementNo, keyword) + .or().like(FormalSettlement::getProjectName, keyword) + .or().like(FormalSettlement::getContractName, keyword)) + .orderByDesc(FormalSettlement::getCreateTime) + .last("limit 200")); + return settlements.stream().map(settlement -> { + BigDecimal received = receivedAmount(settlement.getId(), receiptId); + BigDecimal remaining = money(settlement.getSettlementAmount()).subtract(received).max(BigDecimal.ZERO); + Map row = new LinkedHashMap<>(); + row.put("id", settlement.getId()); + row.put("formalSettlementNo", settlement.getFormalSettlementNo()); + row.put("projectId", settlement.getProjectId()); + row.put("projectName", settlement.getProjectName()); + row.put("deptId", settlement.getDeptId()); + row.put("deptName", settlement.getDeptName()); + row.put("contractId", settlement.getContractId()); + row.put("contractNo", settlement.getContractNo()); + row.put("contractName", settlement.getContractName()); + row.put("payerName", settlement.getPayerName()); + row.put("payeeName", settlement.getPayeeName()); + row.put("settlementAmount", money(settlement.getSettlementAmount())); + row.put("receivedInvoiceAmount", received); + row.put("remainingInvoiceAmount", remaining); + return row; + }).filter(row -> ((BigDecimal) row.get("remainingInvoiceAmount")).compareTo(BigDecimal.ZERO) > 0) + .toList(); + } + + @Override + public Map referenceInformation(String settlementIds) { + List settlements = distinctIds(settlementIds).stream() + .map(this::availableSettlement) + .toList(); + assertCompatible(settlements); + FormalSettlement first = settlements.get(0); + CustomerArchive customer = findCustomer(first.getPayeeName()); + List customerEmails = customer == null ? List.of() : customerContactMapper.selectList( + Wrappers.lambdaQuery() + .eq(CustomerContact::getCustomerId, customer.getId()) + .eq(CustomerContact::getStatus, 1) + .orderByDesc(CustomerContact::getIsDefault) + .orderByAsc(CustomerContact::getCreateTime)).stream() + .map(CustomerContact::getEmail) + .filter(item -> Func.isNotEmpty(item)) + .map(String::trim) + .distinct() + .toList(); + Map result = new LinkedHashMap<>(); + result.put("projectId", first.getProjectId()); + result.put("projectName", first.getProjectName()); + result.put("deptId", first.getDeptId()); + result.put("deptName", first.getDeptName()); + result.put("payerName", first.getPayerName()); + result.put("payeeName", first.getPayeeName()); + result.put("customerEmails", customerEmails); + result.put("departmentEmails", List.of()); + return result; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Long saveDraft(InvoiceReceiptSaveRequest request) { + validateRequest(request); + boolean creating = request.getId() == null; + InvoiceReceipt entity = creating ? new InvoiceReceipt() : editable(request.getId()); + KingdeeInvoicePool invoice = lockedInvoice(request.getKingdeeInvoicePoolId()); + assertInvoiceUnused(invoice, entity.getId()); + + Map requestedRows = distinctSettlementRows( + request.getSettlements()); + Map settlementMap = lockSettlements(requestedRows.keySet().stream().sorted().toList()); + List settlements = requestedRows.keySet().stream().map(settlementMap::get).toList(); + assertCompatible(settlements); + assertInvoiceParties(invoice, settlements.get(0)); + + BigDecimal invoiceAmount = positive(invoice.getInvoiceAmount(), "开票金额"); + BigDecimal allocatedTotal = BigDecimal.ZERO; + for (Map.Entry entry : requestedRows.entrySet()) { + FormalSettlement settlement = settlementMap.get(entry.getKey()); + BigDecimal allocated = nonNegative(entry.getValue().getAllocatedInvoiceAmount(), "分摊发票金额"); + BigDecimal received = receivedAmount(settlement.getId(), entity.getId()); + if (received.add(allocated).compareTo(money(settlement.getSettlementAmount())) > 0) { + throw new ServiceException("结算单" + settlement.getFormalSettlementNo() + + "的累计收票金额不能超过结算总应付含税金额"); + } + allocatedTotal = allocatedTotal.add(allocated); + } + if (allocatedTotal.compareTo(invoiceAmount) != 0) { + throw new ServiceException("分摊发票金额总和必须等于发票开票金额"); + } + + if (creating) { + entity.setApprovalStatus(DRAFT); + entity.setCurrentNode("草稿"); + entity.setCurrentProcessor(AuthUtil.getUserName()); + } + copyInvoiceInformation(entity, invoice); + FormalSettlement first = settlements.get(0); + entity.setProjectId(first.getProjectId()); + entity.setProjectName(first.getProjectName()); + entity.setDeptId(first.getDeptId()); + entity.setDeptName(first.getDeptName()); + entity.setPayerName(first.getPayerName()); + entity.setPayeeName(first.getPayeeName()); + entity.setPhone(limit(Func.isNotEmpty(request.getPhone()) ? request.getPhone() : invoice.getPhone(), + 50, "电话")); + entity.setCustomerEmails(normalizeEmails(Func.isNotEmpty(request.getCustomerEmails()) + ? request.getCustomerEmails() : invoice.getCustomerEmails(), "客户邮箱")); + entity.setDepartmentEmails(normalizeEmails(Func.isNotEmpty(request.getDepartmentEmails()) + ? request.getDepartmentEmails() : invoice.getDepartmentEmails(), "部门邮箱")); + entity.setAttachmentsJson(request.getAttachmentsJson()); + entity.setRemark(limit(request.getRemark(), 200, "备注")); + saveOrUpdate(entity); + + settlementRelationMapper.delete(Wrappers.lambdaQuery() + .eq(InvoiceReceiptSettlement::getInvoiceReceiptId, entity.getId())); + saveRelations(entity.getId(), requestedRows, settlementMap); + record(entity.getId(), creating ? "create" : "save", creating ? "创建草稿" : "保存草稿", + entity.getApprovalStatus(), entity.getApprovalStatus(), null, entity.getKingdeeBillNo()); + return entity.getId(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void removeDraft(Long id) { + InvoiceReceipt entity = existing(id); + if (!DRAFT.equals(entity.getApprovalStatus())) { + throw new ServiceException("仅草稿状态的收票登记允许删除"); + } + settlementRelationMapper.delete(Wrappers.lambdaQuery() + .eq(InvoiceReceiptSettlement::getInvoiceReceiptId, id)); + recordMapper.delete(Wrappers.lambdaQuery() + .eq(InvoiceReceiptRecord::getInvoiceReceiptId, id)); + removeById(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void submit(InvoiceReceiptStatusRequest request) { + InvoiceReceipt entity = editable(requiredId(request)); + validateStoredAllocation(entity); + String fromStatus = entity.getApprovalStatus(); + entity.setApprovalStatus(REVIEWING); + entity.setCurrentNode("收票审核"); + entity.setCurrentProcessor(null); + updateById(entity); + record(entity.getId(), "submit", "提交审批", fromStatus, REVIEWING, null, entity.getKingdeeBillNo()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void approve(InvoiceReceiptStatusRequest request) { + InvoiceReceipt entity = existing(requiredId(request)); + if (!REVIEWING.equals(entity.getApprovalStatus())) { + throw new ServiceException("当前状态不允许审批通过"); + } + validateStoredAllocation(entity); + changeStatus(entity, APPROVED, "approve", "审批通过", null); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void returnBill(InvoiceReceiptStatusRequest request) { + InvoiceReceipt entity = existing(requiredId(request)); + if (!REVIEWING.equals(entity.getApprovalStatus())) { + throw new ServiceException("当前状态不允许驳回"); + } + changeStatus(entity, RETURNED, "return", "已驳回", + limit(required(request.getReason(), "驳回原因"), 200, "驳回原因")); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void voidBill(InvoiceReceiptStatusRequest request) { + InvoiceReceipt entity = existing(requiredId(request)); + if (!APPROVED.equals(entity.getApprovalStatus())) { + throw new ServiceException("仅审批通过的收票登记允许作废"); + } + String reason = limit(required(request.getReason(), "作废原因"), 200, "作废原因"); + entity.setVoidReason(reason); + changeStatus(entity, VOIDED, "void", "已作废", reason); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public String syncKingdee(Long id) { + InvoiceReceipt entity = existing(id); + if (!APPROVED.equals(entity.getApprovalStatus())) { + throw new ServiceException("仅审批通过的收票登记允许同步金蝶状态"); + } + KingdeeInvoicePool invoice = invoicePoolMapper.selectById(entity.getKingdeeInvoicePoolId()); + if (invoice == null || Objects.equals(invoice.getIsDeleted(), 1)) { + throw new ServiceException("金蝶票据池发票不存在"); + } + entity.setKingdeeBillNo(invoice.getKingdeeBillNo()); + entity.setKingdeeStatus(normalizeKingdeeStatus(invoice.getKingdeeStatus())); + updateById(entity); + record(entity.getId(), "sync", "同步金蝶状态", entity.getApprovalStatus(), + entity.getApprovalStatus(), null, entity.getKingdeeBillNo()); + return entity.getKingdeeBillNo(); + } + + private InvoiceReceiptVO toListVO(InvoiceReceipt entity) { + InvoiceReceiptVO vo = InvoiceReceiptWrapper.build().entityVO(entity); + vo.setSettlementNos(settlementRelationMapper.selectList( + Wrappers.lambdaQuery() + .eq(InvoiceReceiptSettlement::getInvoiceReceiptId, entity.getId()) + .orderByAsc(InvoiceReceiptSettlement::getCreateTime)).stream() + .map(InvoiceReceiptSettlement::getFormalSettlementNo) + .collect(Collectors.joining(","))); + return vo; + } + + private void validateRequest(InvoiceReceiptSaveRequest request) { + if (request == null) { + throw new ServiceException("收票登记数据不能为空"); + } + if (request.getKingdeeInvoicePoolId() == null) { + throw new ServiceException("请选择金蝶票据池发票"); + } + if (request.getSettlements() == null || request.getSettlements().isEmpty()) { + throw new ServiceException("请至少选择一张应付正式结算单"); + } + } + + private Map distinctSettlementRows( + List rows) { + Map result = new LinkedHashMap<>(); + for (InvoiceReceiptSaveRequest.SettlementRow row : rows) { + if (row == null || row.getSettlementId() == null) { + throw new ServiceException("正式结算单不能为空"); + } + if (result.putIfAbsent(row.getSettlementId(), row) != null) { + throw new ServiceException("正式结算单不能重复选择"); + } + } + return result; + } + + private Map lockSettlements(List settlementIds) { + Map result = new LinkedHashMap<>(); + for (Long settlementId : settlementIds) { + FormalSettlement settlement = formalSettlementMapper.selectOne( + Wrappers.lambdaQuery() + .eq(FormalSettlement::getId, settlementId) + .last("FOR UPDATE")); + result.put(settlementId, validateSettlement(settlement)); + } + return result; + } + + private FormalSettlement availableSettlement(Long id) { + if (id == null) { + throw new ServiceException("正式结算单不能为空"); + } + return validateSettlement(formalSettlementMapper.selectById(id)); + } + + private FormalSettlement validateSettlement(FormalSettlement settlement) { + if (settlement == null || Objects.equals(settlement.getIsDeleted(), 1)) { + throw new ServiceException("正式结算单不存在"); + } + if (!Objects.equals(settlement.getStatus(), 1) + || !APPROVED.equals(settlement.getApprovalStatus()) + || !"payable".equals(settlement.getSettlementType())) { + throw new ServiceException("只能选择审批通过、未作废的应付正式结算单"); + } + return settlement; + } + + private KingdeeInvoicePool lockedInvoice(Long id) { + KingdeeInvoicePool invoice = invoicePoolMapper.selectOne(Wrappers.lambdaQuery() + .eq(KingdeeInvoicePool::getId, id) + .last("FOR UPDATE")); + if (invoice == null || Objects.equals(invoice.getIsDeleted(), 1) + || !Objects.equals(invoice.getStatus(), 1)) { + throw new ServiceException("金蝶票据池发票不存在或已失效"); + } + required(invoice.getInvoiceNo(), "发票号码"); + return invoice; + } + + private void assertInvoiceUnused(KingdeeInvoicePool invoice, Long excludeReceiptId) { + long count = count(Wrappers.lambdaQuery() + .and(wrapper -> wrapper.eq(InvoiceReceipt::getKingdeeInvoicePoolId, invoice.getId()) + .or().eq(InvoiceReceipt::getInvoiceNo, invoice.getInvoiceNo())) + .ne(excludeReceiptId != null, InvoiceReceipt::getId, excludeReceiptId)); + if (count > 0) { + throw new ServiceException("发票" + invoice.getInvoiceNo() + "已登记,不能重复收票"); + } + } + + private void assertCompatible(List settlements) { + if (settlements.isEmpty()) { + throw new ServiceException("请选择应付正式结算单"); + } + FormalSettlement first = settlements.get(0); + if (settlements.stream().anyMatch(item -> !Objects.equals(first.getProjectId(), item.getProjectId()) + || !Objects.equals(first.getDeptId(), item.getDeptId()) + || !Objects.equals(first.getPayerName(), item.getPayerName()) + || !Objects.equals(first.getPayeeName(), item.getPayeeName()))) { + throw new ServiceException("关联结算单必须属于同一项目、组织及收付款方"); + } + } + + private void assertInvoiceParties(KingdeeInvoicePool invoice, FormalSettlement settlement) { + if (!sameName(invoice.getReceiverName(), settlement.getPayerName()) + || !sameName(invoice.getIssuerName(), settlement.getPayeeName())) { + throw new ServiceException("金蝶发票的开票单位、受票单位与结算单收付款方不一致"); + } + } + + private boolean sameName(String first, String second) { + return Func.isNotEmpty(first) && Func.isNotEmpty(second) && first.trim().equals(second.trim()); + } + + private BigDecimal receivedAmount(Long settlementId, Long excludeReceiptId) { + return activeRelations(settlementId, excludeReceiptId).stream() + .map(InvoiceReceiptSettlement::getAllocatedInvoiceAmount) + .map(this::money) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + + private List activeRelations(Long settlementId, Long excludeReceiptId) { + List relations = settlementRelationMapper.selectList( + Wrappers.lambdaQuery() + .eq(InvoiceReceiptSettlement::getFormalSettlementId, settlementId) + .ne(excludeReceiptId != null, InvoiceReceiptSettlement::getInvoiceReceiptId, excludeReceiptId)); + if (relations.isEmpty()) { + return List.of(); + } + Map receipts = listByIds(relations.stream() + .map(InvoiceReceiptSettlement::getInvoiceReceiptId) + .distinct() + .toList()).stream().collect(Collectors.toMap(InvoiceReceipt::getId, Function.identity())); + return relations.stream().filter(relation -> { + InvoiceReceipt receipt = receipts.get(relation.getInvoiceReceiptId()); + return receipt != null && !VOIDED.equals(receipt.getApprovalStatus()) + && !Objects.equals(receipt.getIsDeleted(), 1); + }).toList(); + } + + private void saveRelations(Long receiptId, + Map rows, + Map settlementMap) { + for (Map.Entry entry : rows.entrySet()) { + FormalSettlement source = settlementMap.get(entry.getKey()); + InvoiceReceiptSettlement relation = new InvoiceReceiptSettlement(); + relation.setInvoiceReceiptId(receiptId); + relation.setFormalSettlementId(source.getId()); + relation.setFormalSettlementNo(source.getFormalSettlementNo()); + relation.setSettlementAmount(money(source.getSettlementAmount())); + relation.setReceivedInvoiceAmount(receivedAmount(source.getId(), receiptId)); + relation.setAllocatedInvoiceAmount(entry.getValue().getAllocatedInvoiceAmount()); + settlementRelationMapper.insert(relation); + } + } + + private void validateStoredAllocation(InvoiceReceipt entity) { + KingdeeInvoicePool invoice = lockedInvoice(entity.getKingdeeInvoicePoolId()); + assertInvoiceUnused(invoice, entity.getId()); + List relations = settlementRelationMapper.selectList( + Wrappers.lambdaQuery() + .eq(InvoiceReceiptSettlement::getInvoiceReceiptId, entity.getId()) + .orderByAsc(InvoiceReceiptSettlement::getCreateTime)); + if (relations.isEmpty()) { + throw new ServiceException("请至少选择一张应付正式结算单"); + } + Map settlementMap = lockSettlements(relations.stream() + .map(InvoiceReceiptSettlement::getFormalSettlementId) + .distinct() + .sorted() + .toList()); + List settlements = relations.stream() + .map(item -> settlementMap.get(item.getFormalSettlementId())) + .toList(); + assertCompatible(settlements); + assertInvoiceParties(invoice, settlements.get(0)); + BigDecimal allocatedTotal = BigDecimal.ZERO; + for (InvoiceReceiptSettlement relation : relations) { + FormalSettlement settlement = settlementMap.get(relation.getFormalSettlementId()); + BigDecimal allocated = nonNegative(relation.getAllocatedInvoiceAmount(), "分摊发票金额"); + BigDecimal received = receivedAmount(settlement.getId(), entity.getId()); + if (received.add(allocated).compareTo(money(settlement.getSettlementAmount())) > 0) { + throw new ServiceException("结算单" + settlement.getFormalSettlementNo() + + "的累计收票金额不能超过结算总应付含税金额"); + } + allocatedTotal = allocatedTotal.add(allocated); + } + if (allocatedTotal.compareTo(positive(invoice.getInvoiceAmount(), "开票金额")) != 0) { + throw new ServiceException("分摊发票金额总和必须等于发票开票金额"); + } + } + + private void copyInvoiceInformation(InvoiceReceipt target, KingdeeInvoicePool source) { + target.setKingdeeInvoicePoolId(source.getId()); + target.setInvoiceNo(limit(source.getInvoiceNo(), 32, "发票号码")); + target.setInvoiceDate(source.getInvoiceDate()); + target.setInvoiceType(source.getInvoiceType()); + target.setTaxRate(nonNegative(source.getTaxRate(), "税率")); + target.setInvoiceAmount(positive(source.getInvoiceAmount(), "开票金额")); + target.setTaxAmount(nonNegative(source.getTaxAmount(), "税额")); + target.setReceiverName(limit(required(source.getReceiverName(), "受票单位"), 100, "受票单位")); + target.setIssuerName(limit(required(source.getIssuerName(), "开票单位"), 100, "开票单位")); + target.setBankName(source.getBankName()); + target.setBankAccount(source.getBankAccount()); + target.setIssuingBank(source.getIssuingBank()); + target.setKingdeeBillNo(source.getKingdeeBillNo()); + target.setKingdeeStatus(normalizeKingdeeStatus(source.getKingdeeStatus())); + } + + private String normalizeKingdeeStatus(String status) { + if ("synced".equals(status) || "failed".equals(status)) { + return status; + } + return "unsynced"; + } + + private void changeStatus(InvoiceReceipt entity, String toStatus, String actionType, + String actionName, String reason) { + String fromStatus = entity.getApprovalStatus(); + entity.setApprovalStatus(toStatus); + entity.setCurrentNode(actionName); + entity.setCurrentProcessor(AuthUtil.getUserName()); + updateById(entity); + record(entity.getId(), actionType, actionName, fromStatus, toStatus, reason, entity.getKingdeeBillNo()); + } + + private void record(Long receiptId, String actionType, String actionName, String fromStatus, + String toStatus, String reason, String kingdeeBillNo) { + InvoiceReceiptRecord record = new InvoiceReceiptRecord(); + record.setInvoiceReceiptId(receiptId); + record.setActionType(actionType); + record.setActionName(actionName); + record.setFromStatus(fromStatus); + record.setToStatus(toStatus); + record.setOperatorName(AuthUtil.getUserName()); + record.setReason(reason); + record.setKingdeeBillNo(kingdeeBillNo); + recordMapper.insert(record); + } + + private InvoiceReceipt existing(Long id) { + if (id == null) { + throw new ServiceException("收票登记ID不能为空"); + } + InvoiceReceipt entity = getById(id); + if (entity == null || Objects.equals(entity.getIsDeleted(), 1)) { + throw new ServiceException("收票登记不存在"); + } + return entity; + } + + private InvoiceReceipt editable(Long id) { + InvoiceReceipt entity = existing(id); + if (!List.of(DRAFT, RETURNED).contains(entity.getApprovalStatus())) { + throw new ServiceException("当前状态不可编辑"); + } + return entity; + } + + private Long requiredId(InvoiceReceiptStatusRequest request) { + if (request == null || request.getId() == null) { + throw new ServiceException("收票登记ID不能为空"); + } + return request.getId(); + } + + private List distinctIds(String ids) { + return ids == null ? List.of() : Func.toLongList(ids).stream().distinct().toList(); + } + + private CustomerArchive findCustomer(String name) { + if (Func.isEmpty(name)) { + return null; + } + return customerArchiveMapper.selectOne(Wrappers.lambdaQuery() + .and(wrapper -> wrapper.eq(CustomerArchive::getFullName, name) + .or().eq(CustomerArchive::getShortName, name)) + .eq(CustomerArchive::getStatus, 1) + .last("limit 1")); + } + + private String normalizeEmails(String value, String name) { + if (Func.isEmpty(value)) { + return ""; + } + List emails = List.of(value.split("[;,,;]")).stream() + .map(String::trim) + .filter(Func::isNotEmpty) + .distinct() + .toList(); + if (emails.size() > 3) { + throw new ServiceException(name + "最多填写3个"); + } + emails.forEach(email -> { + if (email.length() > 100 || !email.matches("^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$")) { + throw new ServiceException(name + "格式不正确"); + } + }); + return limit(String.join(";", emails), 200, name); + } + + private String required(String value, String name) { + if (Func.isEmpty(value)) { + throw new ServiceException(name + "不能为空"); + } + return value.trim(); + } + + private String limit(String value, int length, String name) { + if (value != null && value.length() > length) { + throw new ServiceException(name + "不能超过" + length + "个字符"); + } + return value; + } + + private BigDecimal nonNegative(BigDecimal value, String name) { + if (value == null) { + throw new ServiceException(name + "不能为空"); + } + if (value.compareTo(BigDecimal.ZERO) < 0) { + throw new ServiceException(name + "不能小于0"); + } + return value; + } + + private BigDecimal positive(BigDecimal value, String name) { + BigDecimal result = nonNegative(value, name); + if (result.compareTo(BigDecimal.ZERO) <= 0) { + throw new ServiceException(name + "必须大于0"); + } + return result; + } + + private BigDecimal money(BigDecimal value) { + return value == null ? BigDecimal.ZERO : value; + } +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/PaymentApplicationServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/PaymentApplicationServiceImpl.java new file mode 100644 index 0000000..3ac1348 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/PaymentApplicationServiceImpl.java @@ -0,0 +1,392 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments from this software for such purposes. + * Copyright of this software remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is not liable for any claims arising from secondary or illegal development. + *

+ * Author: Chill Zhuang (bladejava@qq.com) + */ +package org.springblade.transport.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +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.jackson.JsonUtil; +import org.springblade.core.tool.utils.BeanUtil; +import org.springblade.core.tool.utils.Func; +import org.springblade.transport.mapper.FormalSettlementMapper; +import org.springblade.transport.mapper.BillLedgerMapper; +import org.springblade.transport.mapper.BillLedgerUsageMapper; +import org.springblade.transport.mapper.PreSettlementMapper; +import org.springblade.transport.mapper.ProjectApplyMapper; +import org.springblade.transport.mapper.CustomerArchiveMapper; +import org.springblade.transport.mapper.PaymentApplicationInvoiceMapper; +import org.springblade.transport.mapper.PaymentApplicationMapper; +import org.springblade.transport.mapper.PaymentApplicationRecordMapper; +import org.springblade.transport.pojo.dto.PaymentApplicationInvoiceRequest; +import org.springblade.transport.pojo.dto.PaymentApplicationSaveRequest; +import org.springblade.transport.pojo.dto.PaymentApplicationStatusRequest; +import org.springblade.transport.pojo.entity.FormalSettlement; +import org.springblade.transport.pojo.entity.BillLedger; +import org.springblade.transport.pojo.entity.BillLedgerUsage; +import org.springblade.transport.pojo.entity.PreSettlement; +import org.springblade.transport.pojo.entity.ProjectApply; +import org.springblade.transport.pojo.entity.CustomerArchive; +import org.springblade.transport.pojo.entity.PaymentApplication; +import org.springblade.transport.pojo.entity.PaymentApplicationInvoice; +import org.springblade.transport.pojo.vo.PaymentApplicationVO; +import org.springblade.transport.service.IPaymentApplicationService; +import org.springblade.transport.wrapper.PaymentApplicationWrapper; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.Objects; + +/** 付款申请服务实现。 @author Chill */ +@Service +@RequiredArgsConstructor +public class PaymentApplicationServiceImpl extends BaseServiceImpl + implements IPaymentApplicationService { + 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 PaymentApplicationInvoiceMapper invoiceMapper; + private final PaymentApplicationRecordMapper recordMapper; + private final PreSettlementMapper preSettlementMapper; + private final FormalSettlementMapper formalSettlementMapper; + private final ProjectApplyMapper projectApplyMapper; + private final CustomerArchiveMapper customerArchiveMapper; + private final BillLedgerMapper billLedgerMapper; + private final BillLedgerUsageMapper billLedgerUsageMapper; + + @Override + public IPage selectPage(IPage page, PaymentApplicationVO query) { + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery() + .like(Func.isNotEmpty(query.getPaymentNo()), PaymentApplication::getPaymentNo, query.getPaymentNo()) + .like(Func.isNotEmpty(query.getPayeeName()), PaymentApplication::getPayeeName, query.getPayeeName()) + .like(Func.isNotEmpty(query.getProjectName()), PaymentApplication::getProjectName, query.getProjectName()) + .like(Func.isNotEmpty(query.getDeptName()), PaymentApplication::getDeptName, query.getDeptName()) + .like(Func.isNotEmpty(query.getSettlementNo()), PaymentApplication::getSettlementNo, query.getSettlementNo()) + .eq(Func.isNotEmpty(query.getPaymentType()), PaymentApplication::getPaymentType, query.getPaymentType()) + .eq(Func.isNotEmpty(query.getApprovalStatus()), PaymentApplication::getApprovalStatus, query.getApprovalStatus()) + .eq(Func.isNotEmpty(query.getKingdeeStatus()), PaymentApplication::getKingdeeStatus, query.getKingdeeStatus()) + .ge(query.getApplyStartDate() != null, PaymentApplication::getApplyDate, query.getApplyStartDate()) + .le(query.getApplyEndDate() != null, PaymentApplication::getApplyDate, query.getApplyEndDate()) + .orderByDesc(PaymentApplication::getCreateTime); + return page(page, wrapper).convert(item -> { + PaymentApplicationVO vo = PaymentApplicationWrapper.build().entityVO(item); + return vo; + }); + } + + @Override + public PaymentApplicationVO detail(Long id) { + PaymentApplication entity = existing(id); + PaymentApplicationVO vo = PaymentApplicationWrapper.build().entityVO(entity); + vo.setInvoices(invoiceMapper.selectList(Wrappers.lambdaQuery() + .eq(PaymentApplicationInvoice::getPaymentApplicationId, id).orderByAsc(PaymentApplicationInvoice::getLineNo))); + vo.setPaymentRecords(recordMapper.selectList(Wrappers.lambdaQuery() + .eq(org.springblade.transport.pojo.entity.PaymentApplicationRecord::getPaymentApplicationId, id) + .orderByDesc(org.springblade.transport.pojo.entity.PaymentApplicationRecord::getCreateTime))); + return vo; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Long saveDraft(PaymentApplicationSaveRequest request) { + PaymentApplication entity = request.getId() == null ? new PaymentApplication() : editable(request.getId()); + validateRequest(request); + if (entity.getId() == null) { + entity.setPaymentNo(nextNo()); + entity.setApprovalStatus(DRAFT); + entity.setCurrentNode("草稿"); + entity.setKingdeeStatus("unsynced"); + entity.setPaidAmount(BigDecimal.ZERO); + entity.setInvoiceStatus("unmatched"); + } + entity.setPaymentType(request.getPaymentType()); + entity.setPaymentMethod(request.getPaymentMethod()); + entity.setPaymentRatio(request.getPaymentRatio()); + entity.setAppliedAmount(nonNegative(request.getAppliedAmount(), "申请付款金额")); + entity.setReceiptAccountId(request.getReceiptAccountId()); + entity.setReceiptAccountName(request.getReceiptAccountName()); + entity.setBankName(request.getBankName()); + entity.setBankAccount(request.getBankAccount()); + entity.setAttachmentsJson(request.getAttachmentsJson()); + entity.setRemark(limit(request.getRemark(), 200)); + entity.setApplyDate(entity.getApplyDate() == null ? LocalDate.now() : entity.getApplyDate()); + entity.setApplicantName(Func.isEmpty(entity.getApplicantName()) ? AuthUtil.getUserName() : entity.getApplicantName()); + fillReference(entity, request); + fillBillLedger(entity, request); + validateQuota(entity); + saveOrUpdate(entity); + invoiceMapper.delete(Wrappers.lambdaQuery() + .eq(PaymentApplicationInvoice::getPaymentApplicationId, entity.getId())); + int lineNo = 1; + BigDecimal matchedInvoiceAmount = BigDecimal.ZERO; + for (PaymentApplicationInvoiceRequest item : request.getInvoices() == null ? List.of() : request.getInvoices()) { + validateInvoice(item); + PaymentApplicationInvoice invoice = Objects.requireNonNull(BeanUtil.copyProperties(item, PaymentApplicationInvoice.class)); + invoice.setId(null); + invoice.setPaymentApplicationId(entity.getId()); + invoice.setLineNo(lineNo++); + invoiceMapper.insert(invoice); + matchedInvoiceAmount = matchedInvoiceAmount.add(money(item.getMatchedAmount())); + } + if (matchedInvoiceAmount.compareTo(money(entity.getAppliedAmount())) > 0) { + throw new ServiceException("发票匹配金额合计不能超过申请付款金额"); + } + entity.setMatchedInvoiceAmount(matchedInvoiceAmount); + entity.setInvoiceStatus(matchedInvoiceAmount.compareTo(BigDecimal.ZERO) > 0 ? "matched" : "unmatched"); + updateById(entity); + return entity.getId(); + } + + @Override @Transactional(rollbackFor = Exception.class) + public void removeDraft(Long id) { PaymentApplication entity = editable(id); invoiceMapper.delete(Wrappers.lambdaQuery().eq(PaymentApplicationInvoice::getPaymentApplicationId, id)); removeById(entity); } + @Override + @Transactional(rollbackFor = Exception.class) + public void submit(PaymentApplicationStatusRequest request) { + PaymentApplication entity = lockedPayment(request.getId()); + if (!List.of(DRAFT, RETURNED).contains(entity.getApprovalStatus())) { + throw new ServiceException("当前状态不允许提交"); + } + validateSelectedBill(entity, false); + entity.setApprovalStatus(REVIEWING); + entity.setCurrentNode("财务审核"); + entity.setCurrentProcessor(AuthUtil.getUserName()); + updateById(entity); + } + @Override public void returnBill(PaymentApplicationStatusRequest request) { change(request.getId(), REVIEWING, RETURNED, "已驳回", request.getReason()); } + @Override + @Transactional(rollbackFor = Exception.class) + public void voidBill(PaymentApplicationStatusRequest request) { + PaymentApplication entity = lockedPayment(request.getId()); + if (!APPROVED.equals(entity.getApprovalStatus())) throw new ServiceException("仅审批通过的付款申请允许作废"); + if (isBillPayment(entity.getPaymentMethod())) releaseBillBalance(entity); + entity.setApprovalStatus(VOIDED); + entity.setCurrentNode("已作废"); + entity.setCurrentProcessor(AuthUtil.getUserName()); + entity.setRemark(request.getReason() == null ? entity.getRemark() : limit(request.getReason(), 200)); + updateById(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void approve(PaymentApplicationStatusRequest request) { + PaymentApplication entity = lockedPayment(request.getId()); + if (!REVIEWING.equals(entity.getApprovalStatus())) throw new ServiceException("仅审批中的付款申请允许审核"); + if (isBillPayment(entity.getPaymentMethod())) useBillBalance(entity); + entity.setApprovalStatus(APPROVED); entity.setCurrentNode("审批通过"); entity.setCurrentProcessor(AuthUtil.getUserName()); + updateById(entity); + } + + @Override + public String syncKingdee(Long id) { + PaymentApplication entity = existing(id); + if (!APPROVED.equals(entity.getApprovalStatus())) throw new ServiceException("仅审批通过的付款申请允许生成金蝶单据"); + if ("synced".equals(entity.getKingdeeStatus())) return entity.getKingdeeBillNo(); + String no = "FKD" + LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE) + String.format("%05d", count(Wrappers.lambdaQuery().likeRight(PaymentApplication::getKingdeeBillNo, "FKD" + LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE))) + 1); + entity.setKingdeeBillNo(no); entity.setKingdeeStatus("synced"); updateById(entity); return no; + } + + private void validateRequest(PaymentApplicationSaveRequest request) { + if (Func.isEmpty(request.getPaymentType())) throw new ServiceException("付款类型不能为空"); + if (!List.of("project_advance", "progress_advance", "settlement_payment").contains(request.getPaymentType())) throw new ServiceException("付款类型不合法"); + if (Func.isEmpty(request.getPaymentMethod())) throw new ServiceException("付款方式不能为空"); + if (!List.of("bank_transfer", "bank_draft", "commercial_draft").contains(request.getPaymentMethod())) throw new ServiceException("付款方式不合法"); + if (isBillPayment(request.getPaymentMethod()) && request.getBillLedgerId() == null) throw new ServiceException("汇票付款必须选择汇票台账"); + if (request.getPaymentRatio() != null && (request.getPaymentRatio().compareTo(BigDecimal.ZERO) < 0 || request.getPaymentRatio().compareTo(BigDecimal.valueOf(100)) > 0)) throw new ServiceException("付款比例必须在0-100之间"); + if (request.getAppliedAmount() == null || request.getAppliedAmount().compareTo(BigDecimal.ZERO) < 0) throw new ServiceException("申请付款金额不能小于0"); + if (!"project_advance".equals(request.getPaymentType()) && request.getSettlementId() == null && request.getPreSettlementId() == null) throw new ServiceException("非项目预付必须关联结算单"); + if ("project_advance".equals(request.getPaymentType()) && request.getProjectId() == null) throw new ServiceException("项目预付必须选择所属项目"); + if ("progress_advance".equals(request.getPaymentType()) && request.getPreSettlementId() == null) throw new ServiceException("进度预付必须关联预结算单"); + if ("settlement_payment".equals(request.getPaymentType()) && request.getSettlementId() == null) throw new ServiceException("结算付款必须关联正式结算单"); + } + + private void validateInvoice(PaymentApplicationInvoiceRequest invoice) { + BigDecimal invoiceAmount = money(invoice.getInvoiceAmount()); + BigDecimal matchedAmount = money(invoice.getMatchedAmount()); + if (invoiceAmount.compareTo(BigDecimal.ZERO) < 0) { + throw new ServiceException("发票金额不能小于0"); + } + if (matchedAmount.compareTo(BigDecimal.ZERO) < 0) { + throw new ServiceException("发票匹配金额不能小于0"); + } + if (matchedAmount.compareTo(invoiceAmount) > 0) { + throw new ServiceException("单张发票匹配金额不能超过发票金额"); + } + if (invoice.getTaxRate() != null && (invoice.getTaxRate().compareTo(BigDecimal.ZERO) < 0 + || invoice.getTaxRate().compareTo(BigDecimal.valueOf(100)) > 0)) { + throw new ServiceException("发票税率必须在0-100之间"); + } + } + + private void fillReference(PaymentApplication entity, PaymentApplicationSaveRequest request) { + if (request.getSettlementId() != null) { + FormalSettlement source = formalSettlementMapper.selectById(request.getSettlementId()); + if (source == null) throw new ServiceException("正式结算单不存在"); + if (!APPROVED.equals(source.getApprovalStatus())) throw new ServiceException("只能选择审批通过、未作废的正式结算单"); + entity.setSettlementId(source.getId()); entity.setSettlementNo(source.getFormalSettlementNo()); entity.setPreSettlementId(null); entity.setPreSettlementNo(null); + entity.setProjectId(source.getProjectId()); entity.setProjectName(source.getProjectName()); entity.setDeptId(source.getDeptId()); entity.setDeptName(source.getDeptName()); entity.setContractId(source.getContractId()); entity.setContractNo(source.getContractNo()); entity.setContractName(source.getContractName()); entity.setPayerName(source.getPayerName()); entity.setPayeeName(source.getPayeeName()); entity.setSettlementAmount(source.getSettlementAmount()); entity.setPayableAmount(money(source.getSettlementAmount()).subtract(money(source.getAppliedPaymentAmount()))); entity.setBillType("正式结算单"); + } else if (request.getPreSettlementId() != null) { + PreSettlement source = preSettlementMapper.selectById(request.getPreSettlementId()); + if (source == null) throw new ServiceException("预结算单不存在"); + if (!APPROVED.equals(source.getApprovalStatus())) throw new ServiceException("只能选择审批通过、未作废的预结算单"); + entity.setPreSettlementId(source.getId()); entity.setPreSettlementNo(source.getPreSettlementNo()); entity.setSettlementId(null); entity.setSettlementNo(null); entity.setProjectId(source.getProjectId()); entity.setProjectName(source.getProjectName()); entity.setDeptId(source.getDeptId()); entity.setDeptName(source.getDeptName()); entity.setContractId(source.getContractId()); entity.setContractNo(source.getContractNo()); entity.setContractName(source.getContractName()); entity.setPayerName(source.getPayerName()); entity.setPayeeName(source.getPayeeName()); entity.setSettlementAmount(source.getSettlementAmount()); entity.setPayableAmount(money(source.getSettlementAmount()).subtract(money(source.getAdvanceAppliedAmount()))); entity.setBillType("预结算单"); + } else { + entity.setProjectId(request.getProjectId()); entity.setProjectName(request.getProjectName()); entity.setDeptId(request.getDeptId()); entity.setDeptName(request.getDeptName()); entity.setContractId(request.getContractId()); entity.setContractNo(request.getContractNo()); entity.setContractName(request.getContractName()); entity.setPayerName(request.getPayerName()); entity.setPayeeName(request.getPayeeName()); entity.setSettlementAmount(request.getSettlementAmount()); entity.setPayableAmount(request.getPayableAmount()); entity.setBillType(request.getBillType()); + } + if (money(entity.getAppliedAmount()).compareTo(money(entity.getPayableAmount())) > 0 && money(entity.getPayableAmount()).compareTo(BigDecimal.ZERO) > 0) throw new ServiceException("申请付款金额不能超过可付款金额"); + } + + private void validateQuota(PaymentApplication entity) { + BigDecimal usedByProject = sumApplied(Wrappers.lambdaQuery() + .eq(entity.getProjectId() != null, PaymentApplication::getProjectId, entity.getProjectId()) + .ne(entity.getId() != null, PaymentApplication::getId, entity.getId())); + ProjectApply project = entity.getProjectId() == null ? null : projectApplyMapper.selectById(entity.getProjectId()); + if (project != null && project.getFundLimit() != null) { + BigDecimal projectLimit = project.getFundLimit().multiply(BigDecimal.valueOf(10000)); + if (usedByProject.add(money(entity.getAppliedAmount())).compareTo(projectLimit) > 0) throw new ServiceException("申请付款金额超过项目剩余资金使用额度"); + } + if (Func.isNotEmpty(entity.getPayeeName())) { + CustomerArchive customer = customerArchiveMapper.selectOne(Wrappers.lambdaQuery() + .and(wrapper -> wrapper.eq(CustomerArchive::getFullName, entity.getPayeeName()).or().eq(CustomerArchive::getShortName, entity.getPayeeName())) + .eq(CustomerArchive::getIsDeleted, 0).last("limit 1")); + if (customer != null && customer.getMaxCreditLimit() != null) { + BigDecimal customerLimit = customer.getMaxCreditLimit().multiply(BigDecimal.valueOf(10000)); + BigDecimal usedByCustomer = sumApplied(Wrappers.lambdaQuery() + .eq(PaymentApplication::getPayeeName, entity.getPayeeName()).ne(entity.getId() != null, PaymentApplication::getId, entity.getId())); + if (usedByCustomer.add(money(entity.getAppliedAmount())).compareTo(customerLimit) > 0) throw new ServiceException("申请付款金额超过客户剩余资金使用额度"); + } + } + } + + private BigDecimal sumApplied(LambdaQueryWrapper wrapper) { + return list(wrapper.ne(PaymentApplication::getApprovalStatus, VOIDED)).stream() + .map(PaymentApplication::getAppliedAmount).map(this::money).reduce(BigDecimal.ZERO, BigDecimal::add); + } + + private void fillBillLedger(PaymentApplication entity, PaymentApplicationSaveRequest request) { + if (!isBillPayment(request.getPaymentMethod())) { + entity.setBillLedgerId(null); + entity.setBillNo(null); + return; + } + BillLedger ledger = billLedgerMapper.selectById(request.getBillLedgerId()); + validateBill(ledger, entity.getDeptId(), entity.getAppliedAmount(), true); + entity.setBillLedgerId(ledger.getId()); + entity.setBillNo(ledger.getBillNo()); + } + + private void validateSelectedBill(PaymentApplication entity, boolean locked) { + if (!isBillPayment(entity.getPaymentMethod())) return; + BillLedger ledger = locked ? lockedBill(entity.getBillLedgerId()) : billLedgerMapper.selectById(entity.getBillLedgerId()); + validateBill(ledger, entity.getDeptId(), entity.getAppliedAmount(), true); + } + + private void validateBill(BillLedger ledger, Long deptId, BigDecimal amount, boolean checkMaturity) { + if (ledger == null || Objects.equals(ledger.getIsDeleted(), 1)) throw new ServiceException("所选汇票台账不存在"); + if (checkMaturity && (ledger.getMaturityDate() == null || ledger.getMaturityDate().isBefore(LocalDate.now()))) { + throw new ServiceException("所选汇票已到期"); + } + if (money(amount).compareTo(money(ledger.getAvailableBalance())) > 0) throw new ServiceException("申请付款金额超过汇票可用余额"); + if (!departmentAvailable(ledger, deptId)) throw new ServiceException("当前使用部门不在汇票可用部门范围内"); + } + + private void useBillBalance(PaymentApplication entity) { + BillLedger ledger = lockedBill(entity.getBillLedgerId()); + validateBill(ledger, entity.getDeptId(), entity.getAppliedAmount(), true); + BillLedgerUsage exists = billLedgerUsageMapper.selectOne(Wrappers.lambdaQuery() + .eq(BillLedgerUsage::getPaymentApplicationId, entity.getId()).last("FOR UPDATE")); + if (exists != null) throw new ServiceException("该付款申请已生成汇票使用记录"); + BigDecimal amount = money(entity.getAppliedAmount()).setScale(2, RoundingMode.HALF_UP); + ledger.setAvailableBalance(money(ledger.getAvailableBalance()).subtract(amount)); + billLedgerMapper.updateById(ledger); + BillLedgerUsage usage = new BillLedgerUsage(); + usage.setBillLedgerId(ledger.getId()); + usage.setPaymentApplicationId(entity.getId()); + usage.setApplicationNo(entity.getPaymentNo()); + usage.setUsedAmount(amount); + usage.setUseDeptId(entity.getDeptId()); + usage.setUseDeptName(entity.getDeptName()); + usage.setUsageStatus(APPROVED); + usage.setStatus(1); + billLedgerUsageMapper.insert(usage); + } + + private void releaseBillBalance(PaymentApplication entity) { + BillLedgerUsage usage = billLedgerUsageMapper.selectOne(Wrappers.lambdaQuery() + .eq(BillLedgerUsage::getPaymentApplicationId, entity.getId()) + .eq(BillLedgerUsage::getUsageStatus, APPROVED).last("FOR UPDATE")); + if (usage == null) throw new ServiceException("未找到对应的汇票使用记录,无法作废"); + BillLedger ledger = lockedBill(usage.getBillLedgerId()); + ledger.setAvailableBalance(money(ledger.getAvailableBalance()).add(money(usage.getUsedAmount())) + .min(money(ledger.getFaceAmount()))); + billLedgerMapper.updateById(ledger); + usage.setUsageStatus("released"); + billLedgerUsageMapper.updateById(usage); + } + + private BillLedger lockedBill(Long id) { + if (id == null) throw new ServiceException("汇票台账不能为空"); + BillLedger ledger = billLedgerMapper.selectOne(Wrappers.lambdaQuery() + .eq(BillLedger::getId, id).last("FOR UPDATE")); + if (ledger == null || Objects.equals(ledger.getIsDeleted(), 1)) throw new ServiceException("所选汇票台账不存在"); + return ledger; + } + + private PaymentApplication lockedPayment(Long id) { + PaymentApplication entity = baseMapper.selectOne(Wrappers.lambdaQuery() + .eq(PaymentApplication::getId, id).last("FOR UPDATE")); + if (entity == null || Objects.equals(entity.getIsDeleted(), 1)) throw new ServiceException("付款申请不存在"); + return entity; + } + + private boolean departmentAvailable(BillLedger ledger, Long deptId) { + if (Func.isEmpty(ledger.getAvailableDeptIdsJson())) return false; + try { + Object parsed = JsonUtil.parse(ledger.getAvailableDeptIdsJson(), List.class); + if (!(parsed instanceof List values)) return false; + if (values.stream().anyMatch(value -> "all".equals(String.valueOf(value)))) return true; + return deptId != null && values.stream().anyMatch(value -> String.valueOf(deptId).equals(String.valueOf(value))); + } catch (Exception exception) { + throw new ServiceException("汇票可用部门配置不正确"); + } + } + + private boolean isBillPayment(String paymentMethod) { + return List.of("bank_draft", "commercial_draft").contains(paymentMethod); + } + + private void change(Long id, String from, String to, String node, String reason) { PaymentApplication entity = existing(id); if (!from.equals(entity.getApprovalStatus())) throw new ServiceException("当前状态不允许此操作"); entity.setApprovalStatus(to); entity.setCurrentNode(node); entity.setCurrentProcessor(AuthUtil.getUserName()); entity.setRemark(reason == null ? entity.getRemark() : limit(reason, 200)); updateById(entity); } + private PaymentApplication existing(Long id) { PaymentApplication entity = getById(id); if (entity == null || Objects.equals(entity.getIsDeleted(), 1)) throw new ServiceException("付款申请不存在"); return entity; } + private PaymentApplication editable(Long id) { PaymentApplication entity = existing(id); if (!List.of(DRAFT, RETURNED).contains(entity.getApprovalStatus())) throw new ServiceException("当前状态不可编辑"); return entity; } + private String nextNo() { String prefix = "FKD" + LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE); return prefix + String.format("%05d", count(Wrappers.lambdaQuery().likeRight(PaymentApplication::getPaymentNo, prefix)) + 1); } + private BigDecimal nonNegative(BigDecimal value, String name) { if (value == null || value.compareTo(BigDecimal.ZERO) < 0) throw new ServiceException(name + "不能小于0"); return value; } + private BigDecimal money(BigDecimal value) { return value == null ? BigDecimal.ZERO : value; } + private String limit(String value, int length) { if (value != null && value.length() > length) throw new ServiceException("备注不能超过" + length + "个字符"); return value; } +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ReceiptClaimRecordServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ReceiptClaimRecordServiceImpl.java new file mode 100644 index 0000000..04d09a0 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ReceiptClaimRecordServiceImpl.java @@ -0,0 +1,259 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * Author: Chill Zhuang (bladejava@qq.com) + */ +package org.springblade.transport.service.impl; + +import com.baomidou.mybatisplus.core.metadata.IPage; +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.Func; +import org.springblade.transport.mapper.FormalSettlementMapper; +import org.springblade.transport.mapper.KingdeeReceiptFlowMapper; +import org.springblade.transport.mapper.ReceiptClaimMapper; +import org.springblade.transport.mapper.ReceiptClaimSettlementMapper; +import org.springblade.transport.mapper.ReceiptFlowRecordMapper; +import org.springblade.transport.pojo.dto.ReceiptClaimAttachmentsRequest; +import org.springblade.transport.pojo.entity.FormalSettlement; +import org.springblade.transport.pojo.entity.KingdeeReceiptFlow; +import org.springblade.transport.pojo.entity.ReceiptClaim; +import org.springblade.transport.pojo.entity.ReceiptClaimSettlement; +import org.springblade.transport.pojo.entity.ReceiptFlowRecord; +import org.springblade.transport.pojo.vo.ReceiptClaimRecordVO; +import org.springblade.transport.service.IReceiptClaimRecordService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Comparator; +import java.util.List; +import java.util.Objects; + +/** + * 认领记录服务实现类 + * + * @author Chill + */ +@Service +@RequiredArgsConstructor +public class ReceiptClaimRecordServiceImpl extends BaseServiceImpl + implements IReceiptClaimRecordService { + + private static final String CLAIMED = "claimed"; + private static final String VOIDED = "voided"; + private static final String APPROVED = "approved"; + + private final ReceiptClaimSettlementMapper claimSettlementMapper; + private final KingdeeReceiptFlowMapper receiptFlowMapper; + private final FormalSettlementMapper formalSettlementMapper; + private final ReceiptFlowRecordMapper recordMapper; + + @Override + public IPage selectPage(IPage page, + ReceiptClaimRecordVO query) { + page.setRecords(baseMapper.selectClaimRecordPage(page, query, AuthUtil.getUserId())); + page.getRecords().forEach(this::fillStatusNames); + return page; + } + + @Override + public ReceiptClaimRecordVO detail(Long id) { + if (id == null) { + throw new ServiceException("认领记录ID不能为空"); + } + ReceiptClaimRecordVO record = baseMapper.selectClaimRecordDetail(id, AuthUtil.getUserId()); + if (record == null) { + throw new ServiceException("认领记录不存在或无权查看"); + } + record.setSettlements(claimSettlementMapper.selectList( + Wrappers.lambdaQuery() + .eq(ReceiptClaimSettlement::getReceiptClaimId, id) + .orderByAsc(ReceiptClaimSettlement::getCreateTime))); + fillStatusNames(record); + return record; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateAttachments(ReceiptClaimAttachmentsRequest request) { + if (request == null || request.getId() == null) { + throw new ServiceException("认领记录ID不能为空"); + } + if (request.getAttachmentsJson() != null && request.getAttachmentsJson().length() > 2000000) { + throw new ServiceException("附件信息不能超过2MB"); + } + ReceiptClaim claim = baseMapper.selectOne(Wrappers.lambdaQuery() + .eq(ReceiptClaim::getId, request.getId()) + .eq(ReceiptClaim::getClaimerId, AuthUtil.getUserId()) + .last("FOR UPDATE")); + if (claim == null || Objects.equals(claim.getIsDeleted(), 1)) { + throw new ServiceException("认领记录不存在或无权操作"); + } + if (!CLAIMED.equals(normalizeClaimStatus(claim.getClaimStatus()))) { + throw new ServiceException("已作废认领记录不允许修改附件"); + } + claim.setAttachmentsJson(request.getAttachmentsJson()); + updateById(claim); + + ReceiptFlowRecord operationRecord = new ReceiptFlowRecord(); + operationRecord.setReceiptFlowId(claim.getReceiptFlowId()); + operationRecord.setReceiptClaimId(claim.getId()); + operationRecord.setActionType("update_claim_attachments"); + operationRecord.setActionName("维护认领记录附件"); + operationRecord.setFromStatus(CLAIMED); + operationRecord.setToStatus(CLAIMED); + operationRecord.setOperationAmount(BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP)); + operationRecord.setOperatorName(Func.isEmpty(AuthUtil.getUserName()) ? "system" + : AuthUtil.getUserName()); + operationRecord.setContent("更新认领记录附件"); + recordMapper.insert(operationRecord); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public String voidClaim(Long id) { + ReceiptClaim claim = baseMapper.selectOne(Wrappers.lambdaQuery() + .eq(ReceiptClaim::getId, id) + .eq(ReceiptClaim::getClaimerId, AuthUtil.getUserId()) + .last("FOR UPDATE")); + if (claim == null || Objects.equals(claim.getIsDeleted(), 1)) { + throw new ServiceException("认领记录不存在或无权作废"); + } + if (!CLAIMED.equals(normalizeClaimStatus(claim.getClaimStatus()))) { + throw new ServiceException("仅已认领记录允许作废"); + } + + KingdeeReceiptFlow flow = receiptFlowMapper.selectOne( + Wrappers.lambdaQuery() + .eq(KingdeeReceiptFlow::getId, claim.getReceiptFlowId()) + .last("FOR UPDATE")); + if (flow == null || Objects.equals(flow.getIsDeleted(), 1)) { + throw new ServiceException("关联收款流水不存在"); + } + + List relations = claimSettlementMapper.selectList( + Wrappers.lambdaQuery() + .eq(ReceiptClaimSettlement::getReceiptClaimId, claim.getId()) + .eq(ReceiptClaimSettlement::getStatus, 1)); + if (relations.isEmpty()) { + throw new ServiceException("认领记录不存在有效结算分摊"); + } + + List orderedRelations = relations.stream() + .sorted(Comparator.comparing(ReceiptClaimSettlement::getFormalSettlementId)) + .toList(); + for (ReceiptClaimSettlement relation : orderedRelations) { + FormalSettlement settlement = formalSettlementMapper.selectOne( + Wrappers.lambdaQuery() + .eq(FormalSettlement::getId, relation.getFormalSettlementId()) + .last("FOR UPDATE")); + if (settlement == null || Objects.equals(settlement.getIsDeleted(), 1)) { + throw new ServiceException("关联结算单不存在"); + } + BigDecimal paidAfter = money(settlement.getPaidAmount()) + .subtract(money(relation.getAllocatedReceiptAmount())).max(BigDecimal.ZERO); + settlement.setPaidAmount(paidAfter); + settlement.setPaymentStatus(amountStatus(paidAfter, settlement.getSettlementAmount())); + formalSettlementMapper.updateById(settlement); + relation.setStatus(0); + claimSettlementMapper.updateById(relation); + } + + BigDecimal flowClaimedAfter = money(flow.getClaimedAmount()) + .subtract(money(claim.getClaimAmount())).max(BigDecimal.ZERO); + flow.setClaimedAmount(flowClaimedAfter); + flow.setClaimStatus(amountClaimStatus(flowClaimedAfter, flow.getReceiptAmount())); + receiptFlowMapper.updateById(flow); + + String kingdeeBillNo = buildKingdeeBillNo(claim.getId()); + claim.setClaimStatus(VOIDED); + claim.setKingdeeBillNo(kingdeeBillNo); + claim.setKingdeeBillStatus(APPROVED); + claim.setVoidedBy(AuthUtil.getUserId()); + claim.setVoidedByName(Func.isEmpty(AuthUtil.getUserName()) ? claim.getClaimerName() + : AuthUtil.getUserName()); + claim.setVoidedTime(LocalDateTime.now()); + updateById(claim); + + ReceiptFlowRecord operationRecord = new ReceiptFlowRecord(); + operationRecord.setReceiptFlowId(flow.getId()); + operationRecord.setReceiptClaimId(claim.getId()); + operationRecord.setActionType("void_claim"); + operationRecord.setActionName("作废认领记录"); + operationRecord.setFromStatus(CLAIMED); + operationRecord.setToStatus(VOIDED); + operationRecord.setOperationAmount(money(claim.getClaimAmount())); + operationRecord.setOperatorName(Func.isEmpty(AuthUtil.getUserName()) ? "system" + : AuthUtil.getUserName()); + operationRecord.setContent("生成金蝶认领冲单:" + kingdeeBillNo + ",状态:审核通过"); + recordMapper.insert(operationRecord); + return kingdeeBillNo; + } + + private void fillStatusNames(ReceiptClaimRecordVO record) { + record.setClaimStatusName(VOIDED.equals(normalizeClaimStatus(record.getClaimStatus())) + ? "已作废" : "已认领"); + record.setKingdeeBillStatusName(switch (record.getKingdeeBillStatus() == null + ? "" : record.getKingdeeBillStatus()) { + case APPROVED -> "审核通过"; + case "failed" -> "处理失败"; + default -> "未生成"; + }); + } + + private String normalizeClaimStatus(String claimStatus) { + return VOIDED.equals(claimStatus) ? VOIDED : CLAIMED; + } + + private String buildKingdeeBillNo(Long claimId) { + String time = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now()); + String suffix = String.valueOf(claimId); + return "KDCX" + time + suffix.substring(Math.max(0, suffix.length() - 6)); + } + + private String amountClaimStatus(BigDecimal claimedAmount, BigDecimal receiptAmount) { + if (claimedAmount.compareTo(BigDecimal.ZERO) <= 0) { + return "unclaimed"; + } + return claimedAmount.compareTo(money(receiptAmount)) >= 0 ? "claimed" : "partial"; + } + + private String amountStatus(BigDecimal paidAmount, BigDecimal settlementAmount) { + if (paidAmount.compareTo(BigDecimal.ZERO) <= 0) { + return "unpaid"; + } + return paidAmount.compareTo(money(settlementAmount)) >= 0 ? "paid" : "partial"; + } + + private BigDecimal money(BigDecimal amount) { + return amount == null ? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP) + : amount.setScale(2, RoundingMode.HALF_UP); + } +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ReceiptFlowServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ReceiptFlowServiceImpl.java new file mode 100644 index 0000000..9d4e59a --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ReceiptFlowServiceImpl.java @@ -0,0 +1,504 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * Author: Chill Zhuang (bladejava@qq.com) + */ +package org.springblade.transport.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +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.Func; +import org.springblade.system.cache.SysCache; +import org.springblade.system.cache.UserCache; +import org.springblade.system.pojo.entity.Dept; +import org.springblade.transport.mapper.FormalSettlementMapper; +import org.springblade.transport.mapper.KingdeeReceiptFlowMapper; +import org.springblade.transport.mapper.ReceiptClaimMapper; +import org.springblade.transport.mapper.ReceiptClaimSettlementMapper; +import org.springblade.transport.mapper.ReceiptFlowRecordMapper; +import org.springblade.transport.pojo.dto.ReceiptClaimRequest; +import org.springblade.transport.pojo.dto.ReceiptFlowSyncRequest; +import org.springblade.transport.pojo.entity.FormalSettlement; +import org.springblade.transport.pojo.entity.KingdeeReceiptFlow; +import org.springblade.transport.pojo.entity.ReceiptClaim; +import org.springblade.transport.pojo.entity.ReceiptClaimSettlement; +import org.springblade.transport.pojo.entity.ReceiptFlowRecord; +import org.springblade.transport.pojo.vo.ReceiptFlowVO; +import org.springblade.transport.service.IReceiptFlowService; +import org.springblade.transport.support.TransportBusinessSupport; +import org.springblade.transport.wrapper.ReceiptFlowWrapper; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 收款流水服务实现类 + * + * @author Chill + */ +@Service +@RequiredArgsConstructor +public class ReceiptFlowServiceImpl extends BaseServiceImpl + implements IReceiptFlowService { + + private static final String UNCLAIMED = "unclaimed"; + private static final String PARTIAL = "partial"; + private static final String CLAIMED = "claimed"; + private static final String APPROVED = "approved"; + private static final String RECEIVABLE = "receivable"; + + private final ReceiptClaimMapper claimMapper; + private final ReceiptClaimSettlementMapper claimSettlementMapper; + private final ReceiptFlowRecordMapper recordMapper; + private final FormalSettlementMapper formalSettlementMapper; + + @Override + public IPage selectPage(IPage page, ReceiptFlowVO query) { + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery() + .like(Func.isNotEmpty(query.getReceiptNoticeNo()), KingdeeReceiptFlow::getReceiptNoticeNo, + query.getReceiptNoticeNo()) + .like(Func.isNotEmpty(query.getCounterpartyName()), KingdeeReceiptFlow::getCounterpartyName, + query.getCounterpartyName()) + .like(Func.isNotEmpty(query.getCounterpartyBank()), KingdeeReceiptFlow::getCounterpartyBank, + query.getCounterpartyBank()) + .like(Func.isNotEmpty(query.getCounterpartyAccount()), KingdeeReceiptFlow::getCounterpartyAccount, + query.getCounterpartyAccount()) + .like(Func.isNotEmpty(query.getSummary()), KingdeeReceiptFlow::getSummary, query.getSummary()) + .eq(Func.isNotEmpty(query.getClaimStatus()), KingdeeReceiptFlow::getClaimStatus, + query.getClaimStatus()) + .ge(query.getTransactionStartTime() != null, KingdeeReceiptFlow::getTransactionTime, + query.getTransactionStartTime()) + .le(query.getTransactionEndTime() != null, KingdeeReceiptFlow::getTransactionTime, + query.getTransactionEndTime()) + .eq(KingdeeReceiptFlow::getStatus, 1) + .orderByDesc(KingdeeReceiptFlow::getCreateTime); + return page(page, wrapper).convert(ReceiptFlowWrapper.build()::entityVO); + } + + @Override + public ReceiptFlowVO detail(Long id) { + ReceiptFlowVO vo = ReceiptFlowWrapper.build().entityVO(existing(id)); + vo.setClaimerName(UserCache.getUserRealName(AuthUtil.getUserId())); + Long deptId = Func.firstLong(AuthUtil.getDeptId()); + Dept dept = deptId == null ? null : SysCache.getDept(deptId); + vo.setClaimerDeptName(dept == null ? null : dept.getDeptName()); + vo.setClaimDate(LocalDate.now()); + return vo; + } + + @Override + public List> settlementCandidates(String keyword, Long flowId) { + KingdeeReceiptFlow flow = existing(flowId); + List settlements = formalSettlementMapper.selectList( + Wrappers.lambdaQuery() + .eq(FormalSettlement::getSettlementType, RECEIVABLE) + .eq(FormalSettlement::getApprovalStatus, APPROVED) + .eq(FormalSettlement::getStatus, 1) + .and(Func.isNotEmpty(keyword), wrapper -> wrapper + .like(FormalSettlement::getFormalSettlementNo, keyword) + .or().like(FormalSettlement::getProjectName, keyword) + .or().like(FormalSettlement::getContractName, keyword)) + .orderByDesc(FormalSettlement::getCreateTime) + .last("limit 200")); + return settlements.stream() + .filter(settlement -> Func.isEmpty(flow.getCounterpartyName()) + || sameName(flow.getCounterpartyName(), settlement.getPayerName())) + .map(settlement -> candidateRow(settlement)) + .filter(row -> ((BigDecimal) row.get("remainingReceiptAmount")).compareTo(BigDecimal.ZERO) > 0) + .toList(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Long claim(ReceiptClaimRequest request) { + if (request == null || request.getFlowId() == null) { + throw new ServiceException("收款流水ID不能为空"); + } + if (request.getSettlements() == null || request.getSettlements().isEmpty()) { + throw new ServiceException("请选择应收正式结算单"); + } + validateLength(request.getRemark(), 200, "备注不能超过200字"); + + KingdeeReceiptFlow flow = lockedFlow(request.getFlowId()); + Map allocationMap = allocationMap(request.getSettlements()); + List settlementIds = allocationMap.keySet().stream().sorted().toList(); + Map settlementMap = lockSettlements(settlementIds); + List settlements = settlementIds.stream().map(settlementMap::get).toList(); + assertCompatible(settlements); + assertCounterparty(flow, settlements.get(0)); + + Map previousClaimedMap = new LinkedHashMap<>(); + BigDecimal allocatedTotal = BigDecimal.ZERO; + for (FormalSettlement settlement : settlements) { + BigDecimal allocated = allocationMap.get(settlement.getId()); + BigDecimal previousClaimed = settlementClaimedAmount(settlement.getId()); + BigDecimal settlementAmount = positiveMoney(settlement.getSettlementAmount(), "结算总金额"); + if (previousClaimed.add(allocated).compareTo(settlementAmount) > 0) { + throw new ServiceException("结算单" + settlement.getFormalSettlementNo() + + "的累计认领金额不能超过结算总应收含税金额"); + } + previousClaimedMap.put(settlement.getId(), previousClaimed); + allocatedTotal = allocatedTotal.add(allocated); + } + + BigDecimal receiptAmount = positiveMoney(flow.getReceiptAmount(), "收款金额"); + BigDecimal previousFlowClaimed = flowClaimedAmount(flow.getId()); + if (previousFlowClaimed.add(allocatedTotal).compareTo(receiptAmount) > 0) { + throw new ServiceException("本次分摊金额不能超过流水剩余可认领金额"); + } + + Dept dept = TransportBusinessSupport.currentDept("收款流水认领"); + ReceiptClaim claim = new ReceiptClaim(); + claim.setReceiptFlowId(flow.getId()); + claim.setClaimAmount(allocatedTotal); + claim.setClaimerId(AuthUtil.getUserId()); + claim.setClaimerName(UserCache.getUserRealName(AuthUtil.getUserId())); + claim.setClaimerDeptId(dept.getId()); + claim.setClaimerDeptName(dept.getDeptName()); + claim.setClaimDate(LocalDate.now()); + claim.setAttachmentsJson(request.getAttachmentsJson()); + claim.setRemark(trimToNull(request.getRemark())); + claim.setClaimStatus(CLAIMED); + claim.setKingdeeBillStatus("none"); + claimMapper.insert(claim); + + for (FormalSettlement settlement : settlements) { + BigDecimal previousClaimed = previousClaimedMap.get(settlement.getId()); + BigDecimal allocated = allocationMap.get(settlement.getId()); + BigDecimal claimedAfter = previousClaimed.add(allocated); + + ReceiptClaimSettlement relation = new ReceiptClaimSettlement(); + relation.setReceiptClaimId(claim.getId()); + relation.setReceiptFlowId(flow.getId()); + relation.setFormalSettlementId(settlement.getId()); + relation.setFormalSettlementNo(settlement.getFormalSettlementNo()); + relation.setSettlementAmount(money(settlement.getSettlementAmount())); + relation.setClaimedReceiptAmount(previousClaimed); + relation.setAllocatedReceiptAmount(allocated); + claimSettlementMapper.insert(relation); + + settlement.setPaidAmount(claimedAfter); + settlement.setPaymentStatus(amountStatus(claimedAfter, settlement.getSettlementAmount())); + formalSettlementMapper.updateById(settlement); + } + + String fromStatus = normalizeClaimStatus(flow.getClaimStatus()); + BigDecimal claimedAfter = previousFlowClaimed.add(allocatedTotal); + String toStatus = amountClaimStatus(claimedAfter, receiptAmount); + flow.setClaimedAmount(claimedAfter); + flow.setClaimStatus(toStatus); + updateById(flow); + record(flow.getId(), claim.getId(), "claim", "认领收款流水", fromStatus, toStatus, + allocatedTotal, "关联" + settlements.size() + "张应收正式结算单"); + return claim.getId(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public int sync(ReceiptFlowSyncRequest request) { + List rows = request == null || request.getFlows() == null + ? List.of() : request.getFlows(); + if (rows.isEmpty()) { + record(null, null, "sync", "手动同步流水", null, null, BigDecimal.ZERO, + "未接收到金蝶流水数据"); + return 0; + } + + Set serialNumbers = new HashSet<>(); + int syncedCount = 0; + for (ReceiptFlowSyncRequest.FlowRow row : rows) { + validateSyncRow(row); + if (!serialNumbers.add(row.getDetailSerialNo().trim())) { + throw new ServiceException("明细流水号" + row.getDetailSerialNo() + "重复"); + } + KingdeeReceiptFlow entity = baseMapper.selectOne(Wrappers.lambdaQuery() + .eq(KingdeeReceiptFlow::getDetailSerialNo, row.getDetailSerialNo().trim()) + .last("FOR UPDATE")); + boolean created = entity == null; + if (created) { + entity = new KingdeeReceiptFlow(); + entity.setClaimedAmount(BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP)); + entity.setClaimStatus(UNCLAIMED); + } + BigDecimal receiptAmount = positiveMoney(row.getReceiptAmount(), "收款金额"); + BigDecimal claimedAmount = money(entity.getClaimedAmount()); + if (claimedAmount.compareTo(receiptAmount) > 0) { + throw new ServiceException("流水" + row.getDetailSerialNo() + "同步金额不能小于已认领金额"); + } + copySyncRow(entity, row, receiptAmount); + entity.setClaimStatus(amountClaimStatus(claimedAmount, receiptAmount)); + if (created) { + baseMapper.insert(entity); + } else { + baseMapper.updateById(entity); + } + record(entity.getId(), null, "sync", created ? "新增金蝶收款流水" : "更新金蝶收款流水", + entity.getClaimStatus(), entity.getClaimStatus(), BigDecimal.ZERO, entity.getDetailSerialNo()); + syncedCount++; + } + return syncedCount; + } + + private Map candidateRow(FormalSettlement settlement) { + BigDecimal claimedAmount = settlementClaimedAmount(settlement.getId()); + BigDecimal settlementAmount = money(settlement.getSettlementAmount()); + Map row = new LinkedHashMap<>(); + row.put("id", settlement.getId()); + row.put("formalSettlementNo", settlement.getFormalSettlementNo()); + row.put("projectId", settlement.getProjectId()); + row.put("projectName", settlement.getProjectName()); + row.put("deptId", settlement.getDeptId()); + row.put("deptName", settlement.getDeptName()); + row.put("contractId", settlement.getContractId()); + row.put("contractNo", settlement.getContractNo()); + row.put("contractName", settlement.getContractName()); + row.put("payerName", settlement.getPayerName()); + row.put("payeeName", settlement.getPayeeName()); + row.put("settlementAmount", settlementAmount); + row.put("claimedReceiptAmount", claimedAmount); + row.put("remainingReceiptAmount", settlementAmount.subtract(claimedAmount).max(BigDecimal.ZERO)); + return row; + } + + private Map allocationMap(List rows) { + Map allocationMap = new LinkedHashMap<>(); + for (ReceiptClaimRequest.SettlementRow row : rows) { + if (row == null || row.getSettlementId() == null) { + throw new ServiceException("结算单ID不能为空"); + } + if (allocationMap.containsKey(row.getSettlementId())) { + throw new ServiceException("同一张结算单不能重复分摊"); + } + allocationMap.put(row.getSettlementId(), positiveMoney(row.getAllocatedReceiptAmount(), + "分摊收款金额")); + } + return allocationMap; + } + + private Map lockSettlements(List settlementIds) { + List settlements = new ArrayList<>(); + for (Long settlementId : settlementIds) { + FormalSettlement settlement = formalSettlementMapper.selectOne( + Wrappers.lambdaQuery() + .eq(FormalSettlement::getId, settlementId) + .last("FOR UPDATE")); + settlements.add(availableSettlement(settlement)); + } + return settlements.stream().collect(Collectors.toMap(FormalSettlement::getId, + Function.identity(), (first, second) -> first, LinkedHashMap::new)); + } + + private FormalSettlement availableSettlement(FormalSettlement settlement) { + if (settlement == null || Objects.equals(settlement.getIsDeleted(), 1) + || !Objects.equals(settlement.getStatus(), 1) + || !APPROVED.equals(settlement.getApprovalStatus()) + || !RECEIVABLE.equals(settlement.getSettlementType())) { + throw new ServiceException("只能选择审批通过、未作废的应收正式结算单"); + } + return settlement; + } + + private void assertCompatible(List settlements) { + if (settlements.isEmpty()) { + throw new ServiceException("请选择应收正式结算单"); + } + FormalSettlement first = settlements.get(0); + if (settlements.stream().anyMatch(item -> !Objects.equals(first.getProjectId(), item.getProjectId()) + || !Objects.equals(first.getDeptId(), item.getDeptId()) + || !Objects.equals(first.getPayerName(), item.getPayerName()) + || !Objects.equals(first.getPayeeName(), item.getPayeeName()))) { + throw new ServiceException("关联结算单必须属于同一项目、组织及收付款方"); + } + } + + private void assertCounterparty(KingdeeReceiptFlow flow, FormalSettlement settlement) { + if (!sameName(flow.getCounterpartyName(), settlement.getPayerName())) { + throw new ServiceException("对方户名与结算单付款方不一致"); + } + } + + private boolean sameName(String first, String second) { + return Func.isNotEmpty(first) && Func.isNotEmpty(second) && first.trim().equals(second.trim()); + } + + private BigDecimal settlementClaimedAmount(Long settlementId) { + return claimSettlementMapper.selectList(Wrappers.lambdaQuery() + .eq(ReceiptClaimSettlement::getFormalSettlementId, settlementId) + .eq(ReceiptClaimSettlement::getStatus, 1)).stream() + .map(ReceiptClaimSettlement::getAllocatedReceiptAmount) + .map(this::money) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + + private BigDecimal flowClaimedAmount(Long flowId) { + return claimSettlementMapper.selectList(Wrappers.lambdaQuery() + .eq(ReceiptClaimSettlement::getReceiptFlowId, flowId) + .eq(ReceiptClaimSettlement::getStatus, 1)).stream() + .map(ReceiptClaimSettlement::getAllocatedReceiptAmount) + .map(this::money) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + + private KingdeeReceiptFlow lockedFlow(Long flowId) { + KingdeeReceiptFlow flow = baseMapper.selectOne(Wrappers.lambdaQuery() + .eq(KingdeeReceiptFlow::getId, flowId) + .last("FOR UPDATE")); + if (flow == null || Objects.equals(flow.getIsDeleted(), 1) || !Objects.equals(flow.getStatus(), 1)) { + throw new ServiceException("收款流水不存在或已失效"); + } + return flow; + } + + private KingdeeReceiptFlow existing(Long id) { + if (id == null) { + throw new ServiceException("收款流水ID不能为空"); + } + KingdeeReceiptFlow flow = getById(id); + if (flow == null || Objects.equals(flow.getIsDeleted(), 1) || !Objects.equals(flow.getStatus(), 1)) { + throw new ServiceException("收款流水不存在或已失效"); + } + return flow; + } + + private void validateSyncRow(ReceiptFlowSyncRequest.FlowRow row) { + if (row == null) { + throw new ServiceException("金蝶收款流水不能为空"); + } + required(row.getReceiptNoticeNo(), "认领通知单"); + required(row.getPayerName(), "付款人"); + required(row.getCounterpartyName(), "对方户名"); + required(row.getCounterpartyAccount(), "对方账号"); + required(row.getCounterpartyBank(), "对方开户行"); + required(row.getDetailSerialNo(), "明细流水号"); + if (row.getTransactionTime() == null) { + throw new ServiceException("交易时间不能为空"); + } + validateLength(row.getReceiptNoticeNo(), 100, "认领通知单不能超过100字"); + validateLength(row.getPayerName(), 200, "付款人不能超过200字"); + validateLength(row.getCounterpartyName(), 200, "对方户名不能超过200字"); + validateLength(row.getCounterpartyAccount(), 100, "对方账号不能超过100字"); + validateLength(row.getCounterpartyBank(), 200, "对方开户行不能超过200字"); + validateLength(row.getSummary(), 500, "摘要不能超过500字"); + validateLength(row.getDetailSerialNo(), 100, "明细流水号不能超过100字"); + positiveMoney(row.getReceiptAmount(), "收款金额"); + } + + private void copySyncRow(KingdeeReceiptFlow target, ReceiptFlowSyncRequest.FlowRow source, + BigDecimal receiptAmount) { + target.setReceiptNoticeNo(source.getReceiptNoticeNo().trim()); + target.setPayerName(source.getPayerName().trim()); + target.setReceiptAmount(receiptAmount); + target.setCounterpartyName(source.getCounterpartyName().trim()); + target.setCounterpartyAccount(source.getCounterpartyAccount().trim()); + target.setCounterpartyBank(source.getCounterpartyBank().trim()); + target.setSummary(trimToNull(source.getSummary())); + target.setTransactionTime(source.getTransactionTime()); + target.setDetailSerialNo(source.getDetailSerialNo().trim()); + target.setSourceUpdatedTime(source.getSourceUpdatedTime() == null + ? LocalDateTime.now() : source.getSourceUpdatedTime()); + } + + private String amountClaimStatus(BigDecimal claimedAmount, BigDecimal receiptAmount) { + if (claimedAmount.compareTo(BigDecimal.ZERO) <= 0) { + return UNCLAIMED; + } + return claimedAmount.compareTo(money(receiptAmount)) >= 0 ? CLAIMED : PARTIAL; + } + + private String amountStatus(BigDecimal claimedAmount, BigDecimal settlementAmount) { + if (claimedAmount.compareTo(BigDecimal.ZERO) <= 0) { + return "unpaid"; + } + return claimedAmount.compareTo(money(settlementAmount)) >= 0 ? "paid" : "partial"; + } + + private String normalizeClaimStatus(String claimStatus) { + return List.of(UNCLAIMED, PARTIAL, CLAIMED).contains(claimStatus) ? claimStatus : UNCLAIMED; + } + + private BigDecimal positiveMoney(BigDecimal amount, String fieldName) { + if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) { + throw new ServiceException(fieldName + "必须大于0"); + } + if (amount.stripTrailingZeros().scale() > 2) { + throw new ServiceException(fieldName + "最多保留2位小数"); + } + return amount.setScale(2, RoundingMode.HALF_UP); + } + + private BigDecimal money(BigDecimal amount) { + return amount == null ? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP) + : amount.setScale(2, RoundingMode.HALF_UP); + } + + private String required(String value, String fieldName) { + String result = trimToNull(value); + if (result == null) { + throw new ServiceException(fieldName + "不能为空"); + } + return result; + } + + private String trimToNull(String value) { + return value == null || value.trim().isEmpty() ? null : value.trim(); + } + + private void validateLength(String value, int maxLength, String message) { + if (value != null && value.length() > maxLength) { + throw new ServiceException(message); + } + } + + private void record(Long flowId, Long claimId, String actionType, String actionName, + String fromStatus, String toStatus, BigDecimal operationAmount, String content) { + ReceiptFlowRecord record = new ReceiptFlowRecord(); + record.setReceiptFlowId(flowId); + record.setReceiptClaimId(claimId); + record.setActionType(actionType); + record.setActionName(actionName); + record.setFromStatus(fromStatus); + record.setToStatus(toStatus); + record.setOperationAmount(money(operationAmount)); + record.setOperatorName(Func.isEmpty(AuthUtil.getUserName()) ? "system" : AuthUtil.getUserName()); + record.setContent(content); + recordMapper.insert(record); + } +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/BillLedgerWrapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/BillLedgerWrapper.java new file mode 100644 index 0000000..1dba52a --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/BillLedgerWrapper.java @@ -0,0 +1,44 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + */ +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.BillLedger; +import org.springblade.transport.pojo.vo.BillLedgerVO; + +import java.time.LocalDate; +import java.util.Objects; + +/** 汇票台账包装器。 @author Chill */ +public class BillLedgerWrapper extends BaseEntityWrapper { + public static BillLedgerWrapper build() { + return new BillLedgerWrapper(); + } + + @Override + public BillLedgerVO entityVO(BillLedger entity) { + BillLedgerVO vo = Objects.requireNonNull(BeanUtil.copyProperties(entity, BillLedgerVO.class)); + vo.setCreateUserName(UserCache.getUserRealName(entity.getCreateUser())); + vo.setUpdateUserName(UserCache.getUserRealName(entity.getUpdateUser())); + vo.setBillTypeName(switch (entity.getBillType() == null ? "" : entity.getBillType()) { + case "issued" -> "开票"; + case "received" -> "收票"; + default -> entity.getBillType(); + }); + LocalDate today = LocalDate.now(); + if (entity.getMaturityDate() == null) { + vo.setMaturityStatusName(""); + } else if (entity.getMaturityDate().isBefore(today)) { + vo.setMaturityStatusName("已到期"); + } else if (entity.getMaturityDate().isEqual(today)) { + vo.setMaturityStatusName("今日到期"); + } else { + vo.setMaturityStatusName("未到期"); + } + return vo; + } +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/BillPaymentWrapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/BillPaymentWrapper.java new file mode 100644 index 0000000..608e709 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/BillPaymentWrapper.java @@ -0,0 +1,57 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.BillPayment; +import org.springblade.transport.pojo.vo.BillPaymentVO; + +import java.util.Objects; + +/** 汇票付款包装器。 @author Chill */ +public class BillPaymentWrapper extends BaseEntityWrapper { + public static BillPaymentWrapper build() { + return new BillPaymentWrapper(); + } + + @Override + public BillPaymentVO entityVO(BillPayment entity) { + BillPaymentVO vo = Objects.requireNonNull(BeanUtil.copyProperties(entity, BillPaymentVO.class)); + vo.setCreateUserName(UserCache.getUserRealName(entity.getCreateUser())); + vo.setUpdateUserName(UserCache.getUserRealName(entity.getUpdateUser())); + vo.setApprovalStatusName(switch (entity.getApprovalStatus() == null ? "" : entity.getApprovalStatus()) { + case "draft" -> "草稿"; + case "reviewing" -> "审批中"; + case "approved" -> "审批通过"; + case "returned" -> "已驳回"; + case "voided" -> "已作废"; + default -> entity.getApprovalStatus(); + }); + return vo; + } +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/InvoiceApplicationWrapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/InvoiceApplicationWrapper.java new file mode 100644 index 0000000..5528198 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/InvoiceApplicationWrapper.java @@ -0,0 +1,66 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.InvoiceApplication; +import org.springblade.transport.pojo.vo.InvoiceApplicationVO; + +import java.util.Objects; + +/** + * 开票申请包装类 + * + * @author Chill + */ +public class InvoiceApplicationWrapper extends BaseEntityWrapper { + public static InvoiceApplicationWrapper build() { + return new InvoiceApplicationWrapper(); + } + + @Override + public InvoiceApplicationVO entityVO(InvoiceApplication entity) { + InvoiceApplicationVO vo = Objects.requireNonNull(BeanUtil.copyProperties(entity, InvoiceApplicationVO.class)); + vo.setCreateUserName(UserCache.getUserRealName(entity.getCreateUser())); + vo.setApprovalStatusName(switch (entity.getApprovalStatus() == null ? "" : entity.getApprovalStatus()) { + case "draft" -> "草稿"; + case "reviewing" -> "审批中"; + case "approved" -> "审批通过"; + case "returned" -> "已驳回"; + case "voided" -> "已作废"; + default -> entity.getApprovalStatus(); + }); + vo.setKingdeeStatusName(switch (entity.getKingdeeStatus() == null ? "" : entity.getKingdeeStatus()) { + case "unsynced" -> "未同步"; + case "synced" -> "已同步"; + case "failed" -> "同步失败"; + default -> entity.getKingdeeStatus(); + }); + return vo; + } +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/InvoiceReceiptWrapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/InvoiceReceiptWrapper.java new file mode 100644 index 0000000..e1039f0 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/InvoiceReceiptWrapper.java @@ -0,0 +1,67 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.InvoiceReceipt; +import org.springblade.transport.pojo.vo.InvoiceReceiptVO; + +import java.util.Objects; + +/** + * 收票登记包装器 + * + * @author Chill + */ +public class InvoiceReceiptWrapper extends BaseEntityWrapper { + + public static InvoiceReceiptWrapper build() { + return new InvoiceReceiptWrapper(); + } + + @Override + public InvoiceReceiptVO entityVO(InvoiceReceipt entity) { + InvoiceReceiptVO vo = Objects.requireNonNull(BeanUtil.copyProperties(entity, InvoiceReceiptVO.class)); + vo.setCreateUserName(UserCache.getUserRealName(entity.getCreateUser())); + vo.setUpdateUserName(UserCache.getUserRealName(entity.getUpdateUser())); + vo.setApprovalStatusName(switch (entity.getApprovalStatus() == null ? "" : entity.getApprovalStatus()) { + case "draft" -> "草稿"; + case "reviewing" -> "审批中"; + case "approved" -> "审批通过"; + case "returned" -> "已驳回"; + case "voided" -> "已作废"; + default -> entity.getApprovalStatus(); + }); + vo.setKingdeeStatusName(switch (entity.getKingdeeStatus() == null ? "" : entity.getKingdeeStatus()) { + case "synced" -> "已同步"; + case "failed" -> "同步失败"; + default -> "未同步"; + }); + return vo; + } +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/PaymentApplicationWrapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/PaymentApplicationWrapper.java new file mode 100644 index 0000000..7d4f482 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/PaymentApplicationWrapper.java @@ -0,0 +1,59 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments from this software for such purposes. + * Copyright of this software remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is not liable for any claims arising from secondary or illegal development. + *

+ * 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.PaymentApplication; +import org.springblade.transport.pojo.vo.PaymentApplicationVO; + +import java.util.Objects; + +/** 付款申请包装器。 @author Chill */ +public class PaymentApplicationWrapper extends BaseEntityWrapper { + public static PaymentApplicationWrapper build() { return new PaymentApplicationWrapper(); } + @Override + public PaymentApplicationVO entityVO(PaymentApplication entity) { + PaymentApplicationVO vo = Objects.requireNonNull(BeanUtil.copyProperties(entity, PaymentApplicationVO.class)); + vo.setCreateUserName(UserCache.getUserRealName(entity.getCreateUser())); + vo.setUpdateUserName(UserCache.getUserRealName(entity.getUpdateUser())); + vo.setPaymentTypeName(switch (entity.getPaymentType() == null ? "" : entity.getPaymentType()) { + case "project_advance" -> "项目预付"; + case "progress_advance" -> "进度预付"; + case "settlement_payment" -> "结算付款"; + default -> entity.getPaymentType(); + }); + vo.setApprovalStatusName(switch (entity.getApprovalStatus() == null ? "" : entity.getApprovalStatus()) { + case "draft" -> "草稿"; + case "reviewing" -> "审批中"; + case "approved" -> "审批通过"; + case "returned" -> "已驳回"; + case "voided" -> "已作废"; + default -> entity.getApprovalStatus(); + }); + vo.setKingdeeStatusName(switch (entity.getKingdeeStatus() == null ? "" : entity.getKingdeeStatus()) { + case "synced" -> "已生成"; + case "failed" -> "生成失败"; + default -> "未生成"; + }); + return vo; + } +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/ReceiptFlowWrapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/ReceiptFlowWrapper.java new file mode 100644 index 0000000..1aba22d --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/ReceiptFlowWrapper.java @@ -0,0 +1,67 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * 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.KingdeeReceiptFlow; +import org.springblade.transport.pojo.vo.ReceiptFlowVO; + +import java.math.BigDecimal; +import java.util.Objects; + +/** + * 收款流水包装器 + * + * @author Chill + */ +public class ReceiptFlowWrapper extends BaseEntityWrapper { + + public static ReceiptFlowWrapper build() { + return new ReceiptFlowWrapper(); + } + + @Override + public ReceiptFlowVO entityVO(KingdeeReceiptFlow entity) { + ReceiptFlowVO vo = Objects.requireNonNull(BeanUtil.copyProperties(entity, ReceiptFlowVO.class)); + vo.setClaimStatusName(switch (Objects.toString(entity.getClaimStatus(), "")) { + case "partial" -> "部分认领"; + case "claimed" -> "认领完成"; + default -> "未认领"; + }); + BigDecimal receiptAmount = money(entity.getReceiptAmount()); + BigDecimal claimedAmount = money(entity.getClaimedAmount()); + vo.setRemainingAmount(receiptAmount.subtract(claimedAmount).max(BigDecimal.ZERO)); + vo.setCreateUserName(UserCache.getUserRealName(entity.getCreateUser())); + vo.setUpdateUserName(UserCache.getUserRealName(entity.getUpdateUser())); + return vo; + } + + private BigDecimal money(BigDecimal amount) { + return amount == null ? BigDecimal.ZERO : amount; + } +} diff --git a/doc/sql/transport/blade_bill_ledger_20260821.sql b/doc/sql/transport/blade_bill_ledger_20260821.sql new file mode 100644 index 0000000..f3a8eb5 --- /dev/null +++ b/doc/sql/transport/blade_bill_ledger_20260821.sql @@ -0,0 +1,113 @@ +-- 首付款管理 / 汇票台账 +CREATE TABLE IF NOT EXISTS `blade_bill_ledger` ( + `id` bigint(20) NOT NULL, + `tenant_id` varchar(12) COLLATE utf8mb4_general_ci 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', + `bill_no` varchar(32) COLLATE utf8mb4_general_ci NOT NULL COMMENT '票据号码', + `issuer_id` bigint(20) NOT NULL COMMENT '出票单位客商ID', + `issuer_name` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '出票单位', + `receiver_id` bigint(20) DEFAULT NULL COMMENT '收票单位ID', + `receiver_name` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '收票单位', + `bill_type` varchar(30) COLLATE utf8mb4_general_ci NOT NULL COMMENT '汇票类型:issued开票、received收票', + `face_amount` decimal(18,2) NOT NULL COMMENT '票面金额', + `available_balance` decimal(18,2) NOT NULL COMMENT '可用余额', + `issue_date` date NOT NULL COMMENT '出票日期', + `maturity_date` date NOT NULL COMMENT '到期日期', + `available_dept_ids_json` longtext COLLATE utf8mb4_general_ci NOT NULL COMMENT '可用部门ID列表', + `available_dept_names` varchar(500) COLLATE utf8mb4_general_ci NOT NULL COMMENT '可用部门名称', + `fee_bearer_id` bigint(20) NOT NULL COMMENT '费用承担方客商ID', + `fee_bearer_name` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '费用承担方', + `confirmed_discount_rate` decimal(8,4) DEFAULT NULL COMMENT '双方确认贴现率(%)', + `issuing_bank` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '出票行', + `bank_discount_reference_rate` decimal(8,4) DEFAULT NULL COMMENT '银行贴现参考率(%)', + `estimated_discount_fee` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '预计贴现费用', + `attachments_json` longtext COLLATE utf8mb4_general_ci COMMENT '附件JSON', + `remark` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_bill_ledger_no` (`tenant_id`,`bill_no`), + KEY `idx_bill_ledger_maturity` (`tenant_id`,`maturity_date`), + KEY `idx_bill_ledger_parties` (`tenant_id`,`issuer_name`,`receiver_name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='汇票台账'; + +CREATE TABLE IF NOT EXISTS `blade_bill_ledger_usage` ( + `id` bigint(20) NOT NULL, + `tenant_id` varchar(12) COLLATE utf8mb4_general_ci 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', + `bill_ledger_id` bigint(20) NOT NULL COMMENT '汇票台账ID', + `payment_application_id` bigint(20) NOT NULL COMMENT '付款申请ID', + `application_no` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '申请单号', + `used_amount` decimal(18,2) NOT NULL COMMENT '使用金额', + `use_dept_id` bigint(20) DEFAULT NULL COMMENT '使用部门ID', + `use_dept_name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '使用部门', + `usage_status` varchar(30) COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'approved' COMMENT '状态:approved已使用、released已释放', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_bill_ledger_usage_payment` (`tenant_id`,`payment_application_id`), + KEY `idx_bill_ledger_usage_ledger` (`tenant_id`,`bill_ledger_id`,`usage_status`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='汇票使用记录'; + +-- 以下结构升级支持重复执行,兼容前一次已执行 DDL、仅菜单插入失败的场景 +SET @ddl_sql = ( + SELECT IF(COUNT(*) = 0, + 'ALTER TABLE `blade_payment_application` ADD COLUMN `bill_ledger_id` bigint(20) DEFAULT NULL COMMENT ''汇票台账ID'' AFTER `payment_method`', + 'SELECT 1') + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = 'blade_payment_application' + AND COLUMN_NAME = 'bill_ledger_id' +); +PREPARE ddl_stmt FROM @ddl_sql; +EXECUTE ddl_stmt; +DEALLOCATE PREPARE ddl_stmt; + +SET @ddl_sql = ( + SELECT IF(COUNT(*) = 0, + 'ALTER TABLE `blade_payment_application` ADD COLUMN `bill_no` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT ''票据号码'' AFTER `bill_ledger_id`', + 'SELECT 1') + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = 'blade_payment_application' + AND COLUMN_NAME = 'bill_no' +); +PREPARE ddl_stmt FROM @ddl_sql; +EXECUTE ddl_stmt; +DEALLOCATE PREPARE ddl_stmt; + +SET @ddl_sql = ( + SELECT IF(COUNT(*) = 0, + 'ALTER TABLE `blade_payment_application` ADD KEY `idx_payment_application_bill_ledger` (`bill_ledger_id`)', + 'SELECT 1') + FROM information_schema.STATISTICS + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = 'blade_payment_application' + AND INDEX_NAME = 'idx_payment_application_bill_ledger' +); +PREPARE ddl_stmt FROM @ddl_sql; +EXECUTE ddl_stmt; +DEALLOCATE PREPARE ddl_stmt; + +INSERT INTO `blade_menu` + (`id`,`parent_id`,`code`,`name`,`alias`,`path`,`source`,`sort`,`category`,`action`,`is_open`,`component`,`remark`,`is_deleted`) +VALUES + (2090000000000001200,0,'first_payment_management','首付款管理','first_payment_management','/payment','iconfont icon-caidanguanli',6,1,0,1,NULL,'',0), + (2090000000000001280,2090000000000001200,'bill_ledger','汇票台账','bill_ledger','/payment/bill-ledger','',6,1,0,1,NULL,'',0), + (2090000000000001281,2090000000000001280,'bill_ledger_view','查看','bill_ledger_view','','',1,2,0,1,NULL,'',0), + (2090000000000001282,2090000000000001280,'bill_ledger_add','新增','bill_ledger_add','','',2,2,0,1,NULL,'',0), + (2090000000000001283,2090000000000001280,'bill_ledger_edit','编辑','bill_ledger_edit','','',3,2,0,1,NULL,'',0), + (2090000000000001284,2090000000000001280,'bill_ledger_delete','删除','bill_ledger_delete','','',4,2,0,1,NULL,'',0) +ON DUPLICATE KEY UPDATE + `name`=VALUES(`name`), + `path`=VALUES(`path`), + `component`=VALUES(`component`), + `is_deleted`=0; diff --git a/doc/sql/transport/blade_bill_payment_20260822.sql b/doc/sql/transport/blade_bill_payment_20260822.sql new file mode 100644 index 0000000..f9be14a --- /dev/null +++ b/doc/sql/transport/blade_bill_payment_20260822.sql @@ -0,0 +1,79 @@ +-- 首付款管理 / 汇票付款 +CREATE TABLE IF NOT EXISTS `blade_bill_payment` ( + `id` bigint(20) NOT NULL, + `tenant_id` varchar(12) COLLATE utf8mb4_general_ci 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', + `payment_no` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '单据号', + `bill_ledger_id` bigint(20) NOT NULL COMMENT '汇票台账ID', + `bill_no` varchar(32) COLLATE utf8mb4_general_ci NOT NULL COMMENT '票据号码', + `face_amount` decimal(18,2) NOT NULL COMMENT '票面金额', + `available_balance` decimal(18,2) NOT NULL COMMENT '可用余额快照', + `used_amount` decimal(18,2) NOT NULL COMMENT '本次使用金额', + `dept_id` bigint(20) NOT NULL COMMENT '使用部门ID', + `dept_name` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '使用部门', + `payment_date` date NOT 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(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 '备注', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_bill_payment_no` (`tenant_id`,`payment_no`), + KEY `idx_bill_payment_ledger` (`tenant_id`,`bill_ledger_id`), + KEY `idx_bill_payment_date` (`tenant_id`,`payment_date`), + KEY `idx_bill_payment_status` (`tenant_id`,`approval_status`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='汇票付款'; + +-- 统一汇票台账使用记录:兼容付款申请与独立汇票付款单据 +ALTER TABLE `blade_bill_ledger_usage` + MODIFY COLUMN `payment_application_id` bigint(20) DEFAULT NULL COMMENT '付款申请ID'; + +SET @ddl_sql = ( + SELECT IF(COUNT(*) = 0, + 'ALTER TABLE `blade_bill_ledger_usage` ADD COLUMN `bill_payment_id` bigint(20) DEFAULT NULL COMMENT ''汇票付款ID'' AFTER `payment_application_id`', + 'SELECT 1') + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = 'blade_bill_ledger_usage' + AND COLUMN_NAME = 'bill_payment_id' +); +PREPARE ddl_stmt FROM @ddl_sql; +EXECUTE ddl_stmt; +DEALLOCATE PREPARE ddl_stmt; + +SET @ddl_sql = ( + SELECT IF(COUNT(*) = 0, + 'ALTER TABLE `blade_bill_ledger_usage` ADD UNIQUE KEY `uk_bill_ledger_usage_bill_payment` (`tenant_id`,`bill_payment_id`)', + 'SELECT 1') + FROM information_schema.STATISTICS + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = 'blade_bill_ledger_usage' + AND INDEX_NAME = 'uk_bill_ledger_usage_bill_payment' +); +PREPARE ddl_stmt FROM @ddl_sql; +EXECUTE ddl_stmt; +DEALLOCATE PREPARE ddl_stmt; + +INSERT INTO `blade_menu` + (`id`,`parent_id`,`code`,`name`,`alias`,`path`,`source`,`sort`,`category`,`action`,`is_open`,`component`,`remark`,`is_deleted`) +VALUES + (2090000000000001200,0,'first_payment_management','首付款管理','first_payment_management','/payment','iconfont icon-caidanguanli',6,1,0,1,NULL,'',0), + (2090000000000001290,2090000000000001200,'bill_payment','汇票付款','bill_payment','/payment/bill-payment','',7,1,0,1,NULL,'',0), + (2090000000000001291,2090000000000001290,'bill_payment_view','查看','bill_payment_view','','',1,2,0,1,NULL,'',0), + (2090000000000001292,2090000000000001290,'bill_payment_add','新增','bill_payment_add','','',2,2,0,1,NULL,'',0), + (2090000000000001293,2090000000000001290,'bill_payment_edit','编辑','bill_payment_edit','','',3,2,0,1,NULL,'',0), + (2090000000000001294,2090000000000001290,'bill_payment_delete','删除','bill_payment_delete','','',4,2,0,1,NULL,'',0), + (2090000000000001295,2090000000000001290,'bill_payment_submit','提交审批','bill_payment_submit','','',5,2,0,1,NULL,'',0), + (2090000000000001296,2090000000000001290,'bill_payment_approve','审批','bill_payment_approve','','',6,2,0,1,NULL,'',0), + (2090000000000001297,2090000000000001290,'bill_payment_void','作废','bill_payment_void','','',7,2,0,1,NULL,'',0) +ON DUPLICATE KEY UPDATE + `name`=VALUES(`name`), + `path`=VALUES(`path`), + `component`=VALUES(`component`), + `is_deleted`=0; diff --git a/doc/sql/transport/blade_invoice_application_20260821.sql b/doc/sql/transport/blade_invoice_application_20260821.sql new file mode 100644 index 0000000..67aa6a6 --- /dev/null +++ b/doc/sql/transport/blade_invoice_application_20260821.sql @@ -0,0 +1,187 @@ +-- 首付款管理 / 开票管理 +CREATE TABLE IF NOT EXISTS `blade_invoice_application` ( + `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', + `application_no` varchar(100) 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, + `issuer_name` varchar(200) DEFAULT NULL, + `receiver_customer_id` bigint(20) DEFAULT NULL, + `receiver_name` varchar(200) DEFAULT NULL, + `invoice_type` varchar(30) NOT NULL, + `available_invoice_amount` decimal(18,2) NOT NULL DEFAULT '0.00', + `invoice_amount` decimal(18,2) NOT NULL DEFAULT '0.00', + `application_date` date DEFAULT NULL, + `applicant_name` varchar(100) DEFAULT NULL, + `undertaking_dept_id` bigint(20) DEFAULT NULL, + `undertaking_dept_name` varchar(100) DEFAULT NULL, + `department_emails` varchar(320) DEFAULT NULL, + `receiver_invoice_info_id` bigint(20) DEFAULT NULL, + `taxpayer_no` varchar(20) DEFAULT NULL, + `bank_name` varchar(100) DEFAULT NULL, + `bank_account` varchar(50) DEFAULT NULL, + `registered_address` varchar(200) DEFAULT NULL, + `contact_name` varchar(50) DEFAULT NULL, + `contact_phone` varchar(11) DEFAULT NULL, + `email` varchar(100) DEFAULT NULL, + `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_status` varchar(30) NOT NULL DEFAULT 'unsynced', + `synced_time` datetime DEFAULT NULL, + `attachments_json` longtext, + `remark` varchar(200) DEFAULT NULL, + `void_reason` varchar(200) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `uk_invoice_application_no` (`tenant_id`,`application_no`), + KEY `idx_invoice_application_project` (`project_id`), + KEY `idx_invoice_application_status` (`approval_status`), + KEY `idx_invoice_application_kingdee` (`kingdee_status`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='开票申请'; + +CREATE TABLE IF NOT EXISTS `blade_invoice_application_settlement` ( + `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', + `invoice_application_id` bigint(20) NOT NULL, + `formal_settlement_id` bigint(20) NOT NULL, + `formal_settlement_no` varchar(100) NOT NULL, + `settlement_amount` decimal(18,2) NOT NULL DEFAULT '0.00', + `available_invoice_amount` decimal(18,2) NOT NULL DEFAULT '0.00', + `allocated_invoice_amount` decimal(18,2) NOT NULL DEFAULT '0.00', + PRIMARY KEY (`id`), + KEY `idx_invoice_application_settlement` (`invoice_application_id`,`formal_settlement_id`), + KEY `idx_invoice_settlement_formal` (`formal_settlement_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='开票申请关联结算单'; + +CREATE TABLE IF NOT EXISTS `blade_invoice_application_sheet` ( + `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', + `invoice_application_id` bigint(20) NOT NULL, + `sheet_no` int(11) NOT NULL, + `invoice_amount` decimal(18,2) NOT NULL DEFAULT '0.00', + PRIMARY KEY (`id`), + KEY `idx_invoice_application_sheet` (`invoice_application_id`,`sheet_no`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='开票申请发票张次'; + +CREATE TABLE IF NOT EXISTS `blade_invoice_application_line` ( + `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', + `invoice_application_id` bigint(20) NOT NULL, + `invoice_sheet_id` bigint(20) NOT NULL, + `line_no` int(11) NOT NULL, + `goods_category` varchar(100) NOT NULL, + `goods_name` varchar(100) NOT NULL, + `unit` varchar(30) DEFAULT NULL, + `quantity` decimal(18,4) DEFAULT NULL, + `unit_price_no_tax` decimal(18,4) DEFAULT NULL, + `amount_with_tax` decimal(18,2) NOT NULL DEFAULT '0.00', + `tax_rate` decimal(8,4) NOT NULL DEFAULT '0.0000', + `tax_amount` decimal(18,2) NOT NULL DEFAULT '0.00', + `remark` varchar(200) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `idx_invoice_sheet_line` (`invoice_sheet_id`,`line_no`), + KEY `idx_invoice_line_application` (`invoice_application_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='开票申请商品行'; + +CREATE TABLE IF NOT EXISTS `blade_invoice_application_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', + `invoice_application_id` bigint(20) NOT NULL, + `formal_settlement_id` bigint(20) NOT NULL, + `formal_settlement_detail_id` bigint(20) NOT NULL, + `line_no` int(11) NOT NULL, + `document_no` varchar(100) 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(200) DEFAULT NULL, + `cargo_type` varchar(100) DEFAULT NULL, + `transport_quantity` decimal(18,4) DEFAULT NULL, + `quantity_unit` varchar(30) DEFAULT NULL, + `mileage` decimal(18,2) DEFAULT NULL, + `batch_no` varchar(100) DEFAULT NULL, + `freight_amount` decimal(18,2) DEFAULT NULL, + `fee_items_json` longtext, + `settlement_amount_tax` decimal(18,2) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `idx_invoice_application_detail` (`invoice_application_id`,`formal_settlement_detail_id`), + KEY `idx_invoice_detail_settlement` (`formal_settlement_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='开票申请结算明细快照'; + +CREATE TABLE IF NOT EXISTS `blade_invoice_application_record` ( + `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', + `invoice_application_id` bigint(20) NOT NULL, + `action_type` varchar(30) NOT NULL, + `action_name` varchar(50) NOT NULL, + `from_status` varchar(30) DEFAULT NULL, + `to_status` varchar(30) DEFAULT NULL, + `operator_name` varchar(100) DEFAULT NULL, + `reason` varchar(200) DEFAULT NULL, + `kingdee_bill_no` varchar(100) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `idx_invoice_record_application` (`invoice_application_id`,`create_time`) +) 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 +(2090000000000001200,0,'first_payment_management','首付款管理','first_payment_management','/payment','iconfont icon-caidanguanli',6,1,0,1,NULL,'',0), +(2090000000000001220,2090000000000001200,'invoice_application','开票管理','invoice_application','/payment/invoice-application','',2,1,0,1,NULL,'',0), +(2090000000000001221,2090000000000001220,'invoice_application_view','查看','invoice_application_view','','',1,2,0,1,NULL,'',0), +(2090000000000001222,2090000000000001220,'invoice_application_add','新增','invoice_application_add','','',2,2,0,1,NULL,'',0), +(2090000000000001223,2090000000000001220,'invoice_application_edit','编辑','invoice_application_edit','','',3,2,0,1,NULL,'',0), +(2090000000000001224,2090000000000001220,'invoice_application_delete','删除','invoice_application_delete','','',4,2,0,1,NULL,'',0), +(2090000000000001225,2090000000000001220,'invoice_application_submit','提交审批','invoice_application_submit','','',5,2,0,1,NULL,'',0), +(2090000000000001226,2090000000000001220,'invoice_application_approve','审批','invoice_application_approve','','',6,2,0,1,NULL,'',0), +(2090000000000001227,2090000000000001220,'invoice_application_sync','同步金蝶','invoice_application_sync','','',7,2,0,1,NULL,'',0), +(2090000000000001228,2090000000000001220,'invoice_application_export','导出','invoice_application_export','','',8,2,0,1,NULL,'',0), +(2090000000000001229,2090000000000001220,'invoice_application_void','作废','invoice_application_void','','',9,2,0,1,NULL,'',0) +ON DUPLICATE KEY UPDATE `name`=VALUES(`name`),`path`=VALUES(`path`),`component`=VALUES(`component`),`is_deleted`=0; diff --git a/doc/sql/transport/blade_invoice_receipt_20260821.sql b/doc/sql/transport/blade_invoice_receipt_20260821.sql new file mode 100644 index 0000000..d00db21 --- /dev/null +++ b/doc/sql/transport/blade_invoice_receipt_20260821.sql @@ -0,0 +1,145 @@ +-- 首付款管理 / 收票管理 +CREATE TABLE IF NOT EXISTS `blade_kingdee_invoice_pool` ( + `id` bigint(20) NOT NULL, + `tenant_id` varchar(12) COLLATE utf8mb4_general_ci 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', + `invoice_no` varchar(32) COLLATE utf8mb4_general_ci NOT NULL, + `invoice_date` date DEFAULT NULL, + `invoice_type` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, + `tax_rate` decimal(8,4) NOT NULL DEFAULT '0.0000', + `invoice_amount` decimal(18,2) NOT NULL DEFAULT '0.00', + `tax_amount` decimal(18,2) NOT NULL DEFAULT '0.00', + `receiver_name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL, + `issuer_name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL, + `bank_name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL, + `bank_account` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL, + `issuing_bank` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL, + `phone` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, + `customer_emails` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL, + `department_emails` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL, + `kingdee_bill_no` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL, + `kingdee_status` varchar(30) COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'unsynced', + `attachments_json` longtext COLLATE utf8mb4_general_ci, + `source_updated_time` datetime DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `uk_kingdee_invoice_pool_no` (`tenant_id`,`invoice_no`), + KEY `idx_kingdee_invoice_pool_date` (`invoice_date`), + KEY `idx_kingdee_invoice_pool_status` (`kingdee_status`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='金蝶进项发票票据池镜像'; + +CREATE TABLE IF NOT EXISTS `blade_invoice_receipt` ( + `id` bigint(20) NOT NULL, + `tenant_id` varchar(12) COLLATE utf8mb4_general_ci 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', + `kingdee_invoice_pool_id` bigint(20) NOT NULL, + `invoice_no` varchar(32) COLLATE utf8mb4_general_ci NOT NULL, + `invoice_date` date DEFAULT NULL, + `invoice_type` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, + `tax_rate` decimal(8,4) NOT NULL DEFAULT '0.0000', + `invoice_amount` decimal(18,2) NOT NULL DEFAULT '0.00', + `tax_amount` decimal(18,2) NOT NULL DEFAULT '0.00', + `receiver_name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL, + `issuer_name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL, + `project_id` bigint(20) DEFAULT NULL, + `project_name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL, + `dept_id` bigint(20) DEFAULT NULL, + `dept_name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL, + `payer_name` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL, + `payee_name` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL, + `bank_name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL, + `bank_account` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL, + `issuing_bank` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL, + `phone` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, + `customer_emails` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL, + `department_emails` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL, + `approval_status` varchar(30) COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'draft', + `current_node` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL, + `current_processor` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL, + `kingdee_bill_no` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL, + `kingdee_status` varchar(30) COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'unsynced', + `attachments_json` longtext COLLATE utf8mb4_general_ci, + `remark` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL, + `void_reason` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `idx_invoice_receipt_pool` (`kingdee_invoice_pool_id`), + KEY `idx_invoice_receipt_no` (`tenant_id`,`invoice_no`), + KEY `idx_invoice_receipt_project` (`project_id`), + KEY `idx_invoice_receipt_date` (`invoice_date`), + KEY `idx_invoice_receipt_status` (`approval_status`), + KEY `idx_invoice_receipt_kingdee` (`kingdee_status`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='收票登记'; + +CREATE TABLE IF NOT EXISTS `blade_invoice_receipt_settlement` ( + `id` bigint(20) NOT NULL, + `tenant_id` varchar(12) COLLATE utf8mb4_general_ci 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', + `invoice_receipt_id` bigint(20) NOT NULL, + `formal_settlement_id` bigint(20) NOT NULL, + `formal_settlement_no` varchar(100) COLLATE utf8mb4_general_ci NOT NULL, + `settlement_amount` decimal(18,2) NOT NULL DEFAULT '0.00', + `received_invoice_amount` decimal(18,2) NOT NULL DEFAULT '0.00', + `allocated_invoice_amount` decimal(18,2) NOT NULL DEFAULT '0.00', + PRIMARY KEY (`id`), + KEY `idx_invoice_receipt_settlement` (`invoice_receipt_id`,`formal_settlement_id`), + KEY `idx_invoice_receipt_formal` (`formal_settlement_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='收票登记结算单分摊'; + +CREATE TABLE IF NOT EXISTS `blade_invoice_receipt_record` ( + `id` bigint(20) NOT NULL, + `tenant_id` varchar(12) COLLATE utf8mb4_general_ci 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', + `invoice_receipt_id` bigint(20) NOT NULL, + `action_type` varchar(30) COLLATE utf8mb4_general_ci NOT NULL, + `action_name` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, + `from_status` varchar(30) COLLATE utf8mb4_general_ci DEFAULT NULL, + `to_status` varchar(30) COLLATE utf8mb4_general_ci DEFAULT NULL, + `operator_name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL, + `reason` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL, + `kingdee_bill_no` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `idx_invoice_receipt_record` (`invoice_receipt_id`,`create_time`) +) 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 + (2090000000000001200,0,'first_payment_management','首付款管理','first_payment_management','/payment','iconfont icon-caidanguanli',6,1,0,1,NULL,'',0), + (2090000000000001240,2090000000000001200,'invoice_receipt','收票管理','invoice_receipt','/payment/invoice-receipt','',3,1,0,1,NULL,'',0), + (2090000000000001241,2090000000000001240,'invoice_receipt_view','查看','invoice_receipt_view','','',1,2,0,1,NULL,'',0), + (2090000000000001242,2090000000000001240,'invoice_receipt_add','新增','invoice_receipt_add','','',2,2,0,1,NULL,'',0), + (2090000000000001243,2090000000000001240,'invoice_receipt_edit','编辑','invoice_receipt_edit','','',3,2,0,1,NULL,'',0), + (2090000000000001244,2090000000000001240,'invoice_receipt_delete','删除','invoice_receipt_delete','','',4,2,0,1,NULL,'',0), + (2090000000000001245,2090000000000001240,'invoice_receipt_submit','提交审批','invoice_receipt_submit','','',5,2,0,1,NULL,'',0), + (2090000000000001246,2090000000000001240,'invoice_receipt_approve','审批','invoice_receipt_approve','','',6,2,0,1,NULL,'',0), + (2090000000000001247,2090000000000001240,'invoice_receipt_sync','同步金蝶','invoice_receipt_sync','','',7,2,0,1,NULL,'',0), + (2090000000000001248,2090000000000001240,'invoice_receipt_export','导出','invoice_receipt_export','','',8,2,0,1,NULL,'',0), + (2090000000000001249,2090000000000001240,'invoice_receipt_void','作废','invoice_receipt_void','','',9,2,0,1,NULL,'',0) +ON DUPLICATE KEY UPDATE + `name`=VALUES(`name`), + `path`=VALUES(`path`), + `component`=VALUES(`component`), + `is_deleted`=0; diff --git a/doc/sql/transport/blade_payment_application_20260821.sql b/doc/sql/transport/blade_payment_application_20260821.sql new file mode 100644 index 0000000..484c418 --- /dev/null +++ b/doc/sql/transport/blade_payment_application_20260821.sql @@ -0,0 +1,46 @@ +-- 首付款管理 / 付款管理 +CREATE TABLE IF NOT EXISTS `blade_payment_application` ( + `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', + `payment_no` varchar(100) NOT NULL, `payment_type` varchar(30) NOT NULL, `settlement_id` bigint(20) DEFAULT NULL, `settlement_no` varchar(100) DEFAULT NULL, + `pre_settlement_id` bigint(20) DEFAULT NULL, `pre_settlement_no` varchar(100) DEFAULT 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) DEFAULT NULL, `contract_no` varchar(100) DEFAULT NULL, + `contract_name` varchar(100) DEFAULT NULL, `payer_name` varchar(200) DEFAULT NULL, `payee_name` varchar(200) DEFAULT NULL, + `settlement_amount` decimal(18,2) DEFAULT NULL, `payable_amount` decimal(18,2) DEFAULT NULL, `bill_type` varchar(30) DEFAULT NULL, + `payment_ratio` decimal(8,2) DEFAULT NULL, `applied_amount` decimal(18,2) NOT NULL DEFAULT '0.00', `payment_method` varchar(30) NOT NULL, + `receipt_account_id` bigint(20) DEFAULT NULL, `receipt_account_name` varchar(200) DEFAULT NULL, `bank_name` varchar(200) DEFAULT NULL, `bank_account` varchar(100) DEFAULT NULL, + `applicant_name` varchar(100) DEFAULT NULL, `apply_date` date DEFAULT NULL, `invoice_status` varchar(30) DEFAULT 'unmatched', `matched_invoice_amount` decimal(18,2) DEFAULT '0.00', `paid_amount` decimal(18,2) DEFAULT '0.00', + `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_status` varchar(30) NOT NULL DEFAULT 'unsynced', `attachments_json` longtext, `remark` varchar(200) DEFAULT NULL, + PRIMARY KEY (`id`), UNIQUE KEY `uk_payment_application_no` (`tenant_id`,`payment_no`), KEY `idx_payment_application_settlement` (`settlement_id`), KEY `idx_payment_application_apply_date` (`apply_date`), KEY `idx_payment_application_status` (`approval_status`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='付款申请'; + +CREATE TABLE IF NOT EXISTS `blade_payment_application_invoice` ( + `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', + `payment_application_id` bigint(20) NOT NULL, `line_no` int(11) NOT NULL, `settlement_no` varchar(100) DEFAULT NULL, `invoice_no` varchar(100) DEFAULT NULL, `invoice_date` date DEFAULT NULL, + `invoice_type` varchar(30) DEFAULT NULL, `tax_rate` decimal(8,4) DEFAULT NULL, `invoice_amount` decimal(18,2) DEFAULT NULL, `matched_amount` decimal(18,2) DEFAULT NULL, `attachment_json` longtext, + PRIMARY KEY (`id`), KEY `idx_payment_invoice_application` (`payment_application_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='付款申请发票明细'; + +CREATE TABLE IF NOT EXISTS `blade_payment_application_record` ( + `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', + `payment_application_id` bigint(20) NOT NULL, `paid_amount` decimal(18,2) NOT NULL DEFAULT '0.00', `paid_date` date DEFAULT NULL, `payment_no` varchar(100) DEFAULT NULL, `voucher_json` longtext, `kingdee_bill_no` varchar(100) DEFAULT NULL, + PRIMARY KEY (`id`), KEY `idx_payment_record_application` (`payment_application_id`) +) 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 +(2090000000000001200,0,'first_payment_management','首付款管理','first_payment_management','/payment','iconfont icon-caidanguanli',6,1,0,1,NULL,'',0), +(2090000000000001201,2090000000000001200,'payment_application','付款管理','payment_application','/payment/payment-application','',1,1,0,1,NULL,'',0), +(2090000000000001202,2090000000000001201,'payment_application_view','查看','payment_application_view','','',1,2,0,1,NULL,'',0), +(2090000000000001203,2090000000000001201,'payment_application_add','新增','payment_application_add','','',2,2,0,1,NULL,'',0), +(2090000000000001204,2090000000000001201,'payment_application_edit','编辑','payment_application_edit','','',3,2,0,1,NULL,'',0), +(2090000000000001205,2090000000000001201,'payment_application_delete','删除','payment_application_delete','','',4,2,0,1,NULL,'',0), +(2090000000000001206,2090000000000001201,'payment_application_submit','提交审批','payment_application_submit','','',5,2,0,1,NULL,'',0), +(2090000000000001207,2090000000000001201,'payment_application_approve','审批','payment_application_approve','','',6,2,0,1,NULL,'',0), +(2090000000000001208,2090000000000001201,'payment_application_sync','同步金蝶','payment_application_sync','','',7,2,0,1,NULL,'',0), +(2090000000000001209,2090000000000001201,'payment_application_export','导出','payment_application_export','','',8,2,0,1,NULL,'',0), +(2090000000000001210,2090000000000001201,'payment_application_void','作废','payment_application_void','','',9,2,0,1,NULL,'',0) +ON DUPLICATE KEY UPDATE `name`=VALUES(`name`),`path`=VALUES(`path`),`component`=VALUES(`component`),`is_deleted`=0; diff --git a/doc/sql/transport/blade_receipt_flow_20260821.sql b/doc/sql/transport/blade_receipt_flow_20260821.sql new file mode 100644 index 0000000..862d0c7 --- /dev/null +++ b/doc/sql/transport/blade_receipt_flow_20260821.sql @@ -0,0 +1,114 @@ +-- 首付款管理 / 收款流水 +CREATE TABLE IF NOT EXISTS `blade_kingdee_receipt_flow` ( + `id` bigint(20) NOT NULL, + `tenant_id` varchar(12) COLLATE utf8mb4_general_ci 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', + `receipt_notice_no` varchar(100) COLLATE utf8mb4_general_ci NOT NULL, + `payer_name` varchar(200) COLLATE utf8mb4_general_ci NOT NULL, + `receipt_amount` decimal(18,2) NOT NULL DEFAULT '0.00', + `counterparty_name` varchar(200) COLLATE utf8mb4_general_ci NOT NULL, + `counterparty_account` varchar(100) COLLATE utf8mb4_general_ci NOT NULL, + `counterparty_bank` varchar(200) COLLATE utf8mb4_general_ci NOT NULL, + `summary` varchar(500) COLLATE utf8mb4_general_ci DEFAULT NULL, + `transaction_time` datetime NOT NULL, + `detail_serial_no` varchar(100) COLLATE utf8mb4_general_ci NOT NULL, + `claimed_amount` decimal(18,2) NOT NULL DEFAULT '0.00', + `claim_status` varchar(30) COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'unclaimed', + `source_updated_time` datetime DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `uk_receipt_flow_serial` (`tenant_id`,`detail_serial_no`), + KEY `idx_receipt_flow_notice` (`tenant_id`,`receipt_notice_no`), + KEY `idx_receipt_flow_transaction` (`tenant_id`,`transaction_time`), + KEY `idx_receipt_flow_status` (`tenant_id`,`claim_status`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='金蝶收款流水镜像'; + +CREATE TABLE IF NOT EXISTS `blade_receipt_claim` ( + `id` bigint(20) NOT NULL, + `tenant_id` varchar(12) COLLATE utf8mb4_general_ci 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', + `receipt_flow_id` bigint(20) NOT NULL, + `claim_amount` decimal(18,2) NOT NULL DEFAULT '0.00', + `claimer_id` bigint(20) DEFAULT NULL, + `claimer_name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL, + `claimer_dept_id` bigint(20) DEFAULT NULL, + `claimer_dept_name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL, + `claim_date` date DEFAULT NULL, + `attachments_json` longtext COLLATE utf8mb4_general_ci, + `remark` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `idx_receipt_claim_flow` (`receipt_flow_id`), + KEY `idx_receipt_claim_date` (`tenant_id`,`claim_date`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='收款流水认领主单'; + +CREATE TABLE IF NOT EXISTS `blade_receipt_claim_settlement` ( + `id` bigint(20) NOT NULL, + `tenant_id` varchar(12) COLLATE utf8mb4_general_ci 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', + `receipt_claim_id` bigint(20) NOT NULL, + `receipt_flow_id` bigint(20) NOT NULL, + `formal_settlement_id` bigint(20) NOT NULL, + `formal_settlement_no` varchar(100) COLLATE utf8mb4_general_ci NOT NULL, + `settlement_amount` decimal(18,2) NOT NULL DEFAULT '0.00', + `claimed_receipt_amount` decimal(18,2) NOT NULL DEFAULT '0.00', + `allocated_receipt_amount` decimal(18,2) NOT NULL DEFAULT '0.00', + PRIMARY KEY (`id`), + KEY `idx_receipt_claim_settlement` (`receipt_claim_id`,`formal_settlement_id`), + KEY `idx_receipt_claim_formal` (`formal_settlement_id`,`status`), + KEY `idx_receipt_claim_flow_settlement` (`receipt_flow_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='收款认领结算单分摊'; + +CREATE TABLE IF NOT EXISTS `blade_receipt_flow_record` ( + `id` bigint(20) NOT NULL, + `tenant_id` varchar(12) COLLATE utf8mb4_general_ci 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', + `receipt_flow_id` bigint(20) DEFAULT NULL, + `receipt_claim_id` bigint(20) DEFAULT NULL, + `action_type` varchar(30) COLLATE utf8mb4_general_ci NOT NULL, + `action_name` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, + `from_status` varchar(30) COLLATE utf8mb4_general_ci DEFAULT NULL, + `to_status` varchar(30) COLLATE utf8mb4_general_ci DEFAULT NULL, + `operation_amount` decimal(18,2) NOT NULL DEFAULT '0.00', + `operator_name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL, + `content` varchar(500) COLLATE utf8mb4_general_ci DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `idx_receipt_flow_record_flow` (`receipt_flow_id`,`create_time`), + KEY `idx_receipt_flow_record_claim` (`receipt_claim_id`) +) 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 + (2090000000000001200,0,'first_payment_management','首付款管理','first_payment_management','/payment','iconfont icon-caidanguanli',6,1,0,1,NULL,'',0), + (2090000000000001260,2090000000000001200,'receipt_flow','收款流水','receipt_flow','/payment/receipt-flow','',4,1,0,1,NULL,'',0), + (2090000000000001261,2090000000000001260,'receipt_flow_view','查看','receipt_flow_view','','',1,2,0,1,NULL,'',0), + (2090000000000001262,2090000000000001260,'receipt_flow_claim','认领','receipt_flow_claim','','',2,2,0,1,NULL,'',0), + (2090000000000001263,2090000000000001260,'receipt_flow_sync','手动同步流水','receipt_flow_sync','','',3,2,0,1,NULL,'',0) +ON DUPLICATE KEY UPDATE + `name`=VALUES(`name`), + `path`=VALUES(`path`), + `component`=VALUES(`component`), + `is_deleted`=0; diff --git a/doc/sql/transport/blade_receipt_flow_claim_record_20260821.sql b/doc/sql/transport/blade_receipt_flow_claim_record_20260821.sql new file mode 100644 index 0000000..8ed83d7 --- /dev/null +++ b/doc/sql/transport/blade_receipt_flow_claim_record_20260821.sql @@ -0,0 +1,107 @@ +-- 首付款管理 / 认领记录 +-- 以下结构升级支持重复执行,兼容前一次已执行 DDL、仅菜单插入失败的场景 +SET @ddl_sql = ( + SELECT IF(COUNT(*) = 0, + 'ALTER TABLE `blade_receipt_claim` ADD COLUMN `claim_status` varchar(30) COLLATE utf8mb4_general_ci NOT NULL DEFAULT ''claimed'' COMMENT ''认领状态:claimed已认领、voided已作废'' AFTER `remark`', + 'SELECT 1') + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'blade_receipt_claim' AND COLUMN_NAME = 'claim_status' +); +PREPARE ddl_stmt FROM @ddl_sql; +EXECUTE ddl_stmt; +DEALLOCATE PREPARE ddl_stmt; + +SET @ddl_sql = ( + SELECT IF(COUNT(*) = 0, + 'ALTER TABLE `blade_receipt_claim` ADD COLUMN `kingdee_bill_no` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT ''金蝶认领冲单号'' AFTER `claim_status`', + 'SELECT 1') + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'blade_receipt_claim' AND COLUMN_NAME = 'kingdee_bill_no' +); +PREPARE ddl_stmt FROM @ddl_sql; +EXECUTE ddl_stmt; +DEALLOCATE PREPARE ddl_stmt; + +SET @ddl_sql = ( + SELECT IF(COUNT(*) = 0, + 'ALTER TABLE `blade_receipt_claim` ADD COLUMN `kingdee_bill_status` varchar(30) COLLATE utf8mb4_general_ci NOT NULL DEFAULT ''none'' COMMENT ''金蝶单据状态'' AFTER `kingdee_bill_no`', + 'SELECT 1') + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'blade_receipt_claim' AND COLUMN_NAME = 'kingdee_bill_status' +); +PREPARE ddl_stmt FROM @ddl_sql; +EXECUTE ddl_stmt; +DEALLOCATE PREPARE ddl_stmt; + +SET @ddl_sql = ( + SELECT IF(COUNT(*) = 0, + 'ALTER TABLE `blade_receipt_claim` ADD COLUMN `voided_by` bigint(20) DEFAULT NULL COMMENT ''作废人'' AFTER `kingdee_bill_status`', + 'SELECT 1') + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'blade_receipt_claim' AND COLUMN_NAME = 'voided_by' +); +PREPARE ddl_stmt FROM @ddl_sql; +EXECUTE ddl_stmt; +DEALLOCATE PREPARE ddl_stmt; + +SET @ddl_sql = ( + SELECT IF(COUNT(*) = 0, + 'ALTER TABLE `blade_receipt_claim` ADD COLUMN `voided_by_name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT ''作废人姓名'' AFTER `voided_by`', + 'SELECT 1') + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'blade_receipt_claim' AND COLUMN_NAME = 'voided_by_name' +); +PREPARE ddl_stmt FROM @ddl_sql; +EXECUTE ddl_stmt; +DEALLOCATE PREPARE ddl_stmt; + +SET @ddl_sql = ( + SELECT IF(COUNT(*) = 0, + 'ALTER TABLE `blade_receipt_claim` ADD COLUMN `voided_time` datetime DEFAULT NULL COMMENT ''作废时间'' AFTER `voided_by_name`', + 'SELECT 1') + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'blade_receipt_claim' AND COLUMN_NAME = 'voided_time' +); +PREPARE ddl_stmt FROM @ddl_sql; +EXECUTE ddl_stmt; +DEALLOCATE PREPARE ddl_stmt; + +SET @ddl_sql = ( + SELECT IF(COUNT(*) = 0, + 'ALTER TABLE `blade_receipt_claim` ADD KEY `idx_receipt_claim_owner_status` (`tenant_id`,`claimer_id`,`claim_status`,`claim_date`)', + 'SELECT 1') + FROM information_schema.STATISTICS + WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'blade_receipt_claim' AND INDEX_NAME = 'idx_receipt_claim_owner_status' +); +PREPARE ddl_stmt FROM @ddl_sql; +EXECUTE ddl_stmt; +DEALLOCATE PREPARE ddl_stmt; + +SET @ddl_sql = ( + SELECT IF(COUNT(*) = 0, + 'ALTER TABLE `blade_receipt_claim` ADD KEY `idx_receipt_claim_kingdee_status` (`tenant_id`,`kingdee_bill_status`)', + 'SELECT 1') + FROM information_schema.STATISTICS + WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'blade_receipt_claim' AND INDEX_NAME = 'idx_receipt_claim_kingdee_status' +); +PREPARE ddl_stmt FROM @ddl_sql; +EXECUTE ddl_stmt; +DEALLOCATE PREPARE ddl_stmt; + +UPDATE `blade_receipt_claim` +SET `claim_status` = 'claimed', + `kingdee_bill_status` = 'none' +WHERE `claim_status` IS NULL OR `claim_status` = ''; + +INSERT INTO `blade_menu` + (`id`,`parent_id`,`code`,`name`,`alias`,`path`,`source`,`sort`,`category`,`action`,`is_open`,`component`,`remark`,`is_deleted`) +VALUES + (2090000000000001200,0,'first_payment_management','首付款管理','first_payment_management','/payment','iconfont icon-caidanguanli',6,1,0,1,NULL,'',0), + (2090000000000001270,2090000000000001200,'receipt_claim_record','认领记录','receipt_claim_record','/payment/receipt-claim-record','',5,1,0,1,NULL,'',0), + (2090000000000001271,2090000000000001270,'receipt_claim_record_view','查看','receipt_claim_record_view','','',1,2,0,1,NULL,'',0), + (2090000000000001272,2090000000000001270,'receipt_claim_record_void','作废','receipt_claim_record_void','','',2,2,0,1,NULL,'',0) +ON DUPLICATE KEY UPDATE + `name`=VALUES(`name`), + `path`=VALUES(`path`), + `component`=VALUES(`component`), + `is_deleted`=0;