mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-22 23:31:52 +08:00
Merge remote-tracking branch 'upstream/develop' into develop
This commit is contained in:
commit
72113bbbc6
@ -72,6 +72,9 @@ ErrorCode PURCHASE_ORDER_ITEM_RETURN_FAIL_IN_EXCEED = new ErrorCode(1_030_101_00
|
||||
ErrorCode SALE_OUT_APPROVE_FAIL = new ErrorCode(1_020_202_003, "审核失败,只有未审核的出库单才能审核");
|
||||
ErrorCode SALE_OUT_NO_EXISTS = new ErrorCode(1_020_202_004, "生成出库单失败,请重新提交");
|
||||
ErrorCode SALE_OUT_UPDATE_FAIL_APPROVE = new ErrorCode(1_020_202_005, "销售出库单({})已审核,无法修改");
|
||||
ErrorCode SALE_OUT_NOT_APPROVE = new ErrorCode(1_020_202_006, "销售出库单未审核,无法操作");
|
||||
ErrorCode SALE_OUT_FAIL_RECEIPT_PRICE_EXCEED = new ErrorCode(1_020_202_007, "收款金额({})超过销售出库单总金额({})");
|
||||
ErrorCode SALE_OUT_PROCESS_FAIL_EXISTS_RECEIPT = new ErrorCode(1_020_202_008, "反审核失败,已存在对应的收款单");
|
||||
|
||||
// ========== ERP 销售退货(1-030-203-000) ==========
|
||||
ErrorCode SALE_RETURN_NOT_EXISTS = new ErrorCode(1_020_203_000, "销售退货单不存在");
|
||||
@ -80,6 +83,9 @@ ErrorCode PURCHASE_ORDER_ITEM_RETURN_FAIL_IN_EXCEED = new ErrorCode(1_030_101_00
|
||||
ErrorCode SALE_RETURN_APPROVE_FAIL = new ErrorCode(1_020_203_003, "审核失败,只有未审核的退货单才能审核");
|
||||
ErrorCode SALE_RETURN_NO_EXISTS = new ErrorCode(1_020_203_004, "生成退货单失败,请重新提交");
|
||||
ErrorCode SALE_RETURN_UPDATE_FAIL_APPROVE = new ErrorCode(1_020_203_005, "销售退货单({})已审核,无法修改");
|
||||
ErrorCode SALE_RETURN_NOT_APPROVE = new ErrorCode(1_020_203_006, "销售退货单未审核,无法操作");
|
||||
ErrorCode SALE_RETURN_FAIL_REFUND_PRICE_EXCEED = new ErrorCode(1_020_203_007, "退款金额({})超过销售退货单总金额({})");
|
||||
ErrorCode SALE_RETURN_PROCESS_FAIL_EXISTS_REFUND = new ErrorCode(1_020_203_008, "反审核失败,已存在对应的退款单");
|
||||
|
||||
// ========== ERP 仓库 1-030-400-000 ==========
|
||||
ErrorCode WAREHOUSE_NOT_EXISTS = new ErrorCode(1_030_400_000, "仓库不存在");
|
||||
@ -151,4 +157,12 @@ ErrorCode PURCHASE_ORDER_ITEM_RETURN_FAIL_IN_EXCEED = new ErrorCode(1_030_101_00
|
||||
ErrorCode FINANCE_PAYMENT_NO_EXISTS = new ErrorCode(1_030_601_004, "生成付款单号失败,请重新提交");
|
||||
ErrorCode FINANCE_PAYMENT_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_601_005, "付款单({})已审核,无法修改");
|
||||
|
||||
// ========== ERP 收款单 1-030-602-000 ==========
|
||||
ErrorCode FINANCE_RECEIPT_NOT_EXISTS = new ErrorCode(1_030_602_000, "收款单不存在");
|
||||
ErrorCode FINANCE_RECEIPT_DELETE_FAIL_APPROVE = new ErrorCode(1_030_602_001, "收款单({})已审核,无法删除");
|
||||
ErrorCode FINANCE_RECEIPT_PROCESS_FAIL = new ErrorCode(1_030_602_002, "反审核失败,只有已审核的收款单才能反审核");
|
||||
ErrorCode FINANCE_RECEIPT_APPROVE_FAIL = new ErrorCode(1_030_602_003, "审核失败,只有未审核的收款单才能审核");
|
||||
ErrorCode FINANCE_RECEIPT_NO_EXISTS = new ErrorCode(1_030_602_004, "生成收款单号失败,请重新提交");
|
||||
ErrorCode FINANCE_RECEIPT_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_602_005, "收款单({})已审核,无法修改");
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,153 @@
|
||||
package cn.iocoder.yudao.module.erp.controller.admin.finance;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
||||
import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.receipt.ErpFinanceReceiptPageReqVO;
|
||||
import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.receipt.ErpFinanceReceiptRespVO;
|
||||
import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.receipt.ErpFinanceReceiptSaveReqVO;
|
||||
import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpAccountDO;
|
||||
import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinanceReceiptDO;
|
||||
import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinanceReceiptItemDO;
|
||||
import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO;
|
||||
import cn.iocoder.yudao.module.erp.service.finance.ErpAccountService;
|
||||
import cn.iocoder.yudao.module.erp.service.finance.ErpFinanceReceiptService;
|
||||
import cn.iocoder.yudao.module.erp.service.sale.ErpCustomerService;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
||||
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||
|
||||
@Tag(name = "管理后台 - ERP 收款单")
|
||||
@RestController
|
||||
@RequestMapping("/erp/finance-receipt")
|
||||
@Validated
|
||||
public class ErpFinanceReceiptController {
|
||||
|
||||
@Resource
|
||||
private ErpFinanceReceiptService financeReceiptService;
|
||||
@Resource
|
||||
private ErpCustomerService customerService;
|
||||
@Resource
|
||||
private ErpAccountService accountService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建收款单")
|
||||
@PreAuthorize("@ss.hasPermission('erp:finance-receipt:create')")
|
||||
public CommonResult<Long> createFinanceReceipt(@Valid @RequestBody ErpFinanceReceiptSaveReqVO createReqVO) {
|
||||
return success(financeReceiptService.createFinanceReceipt(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新收款单")
|
||||
@PreAuthorize("@ss.hasPermission('erp:finance-receipt:update')")
|
||||
public CommonResult<Boolean> updateFinanceReceipt(@Valid @RequestBody ErpFinanceReceiptSaveReqVO updateReqVO) {
|
||||
financeReceiptService.updateFinanceReceipt(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/update-status")
|
||||
@Operation(summary = "更新收款单的状态")
|
||||
@PreAuthorize("@ss.hasPermission('erp:finance-receipt:update-status')")
|
||||
public CommonResult<Boolean> updateFinanceReceiptStatus(@RequestParam("id") Long id,
|
||||
@RequestParam("status") Integer status) {
|
||||
financeReceiptService.updateFinanceReceiptStatus(id, status);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除收款单")
|
||||
@Parameter(name = "ids", description = "编号数组", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('erp:finance-receipt:delete')")
|
||||
public CommonResult<Boolean> deleteFinanceReceipt(@RequestParam("ids") List<Long> ids) {
|
||||
financeReceiptService.deleteFinanceReceipt(ids);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得收款单")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('erp:finance-receipt:query')")
|
||||
public CommonResult<ErpFinanceReceiptRespVO> getFinanceReceipt(@RequestParam("id") Long id) {
|
||||
ErpFinanceReceiptDO receipt = financeReceiptService.getFinanceReceipt(id);
|
||||
if (receipt == null) {
|
||||
return success(null);
|
||||
}
|
||||
List<ErpFinanceReceiptItemDO> receiptItemList = financeReceiptService.getFinanceReceiptItemListByReceiptId(id);
|
||||
return success(BeanUtils.toBean(receipt, ErpFinanceReceiptRespVO.class, financeReceiptVO ->
|
||||
financeReceiptVO.setItems(BeanUtils.toBean(receiptItemList, ErpFinanceReceiptRespVO.Item.class))));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得收款单分页")
|
||||
@PreAuthorize("@ss.hasPermission('erp:finance-receipt:query')")
|
||||
public CommonResult<PageResult<ErpFinanceReceiptRespVO>> getFinanceReceiptPage(@Valid ErpFinanceReceiptPageReqVO pageReqVO) {
|
||||
PageResult<ErpFinanceReceiptDO> pageResult = financeReceiptService.getFinanceReceiptPage(pageReqVO);
|
||||
return success(buildFinanceReceiptVOPageResult(pageResult));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出收款单 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('erp:finance-receipt:export')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void exportFinanceReceiptExcel(@Valid ErpFinanceReceiptPageReqVO pageReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<ErpFinanceReceiptRespVO> list = buildFinanceReceiptVOPageResult(financeReceiptService.getFinanceReceiptPage(pageReqVO)).getList();
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "收款单.xls", "数据", ErpFinanceReceiptRespVO.class, list);
|
||||
}
|
||||
|
||||
private PageResult<ErpFinanceReceiptRespVO> buildFinanceReceiptVOPageResult(PageResult<ErpFinanceReceiptDO> pageResult) {
|
||||
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||
return PageResult.empty(pageResult.getTotal());
|
||||
}
|
||||
// 1.1 收款项
|
||||
List<ErpFinanceReceiptItemDO> receiptItemList = financeReceiptService.getFinanceReceiptItemListByReceiptIds(
|
||||
convertSet(pageResult.getList(), ErpFinanceReceiptDO::getId));
|
||||
Map<Long, List<ErpFinanceReceiptItemDO>> financeReceiptItemMap = convertMultiMap(receiptItemList, ErpFinanceReceiptItemDO::getReceiptId);
|
||||
// 1.2 客户信息
|
||||
Map<Long, ErpCustomerDO> customerMap = customerService.getCustomerMap(
|
||||
convertSet(pageResult.getList(), ErpFinanceReceiptDO::getCustomerId));
|
||||
// 1.3 结算账户信息
|
||||
Map<Long, ErpAccountDO> accountMap = accountService.getAccountMap(
|
||||
convertSet(pageResult.getList(), ErpFinanceReceiptDO::getAccountId));
|
||||
// 1.4 管理员信息
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(pageResult.getList(),
|
||||
contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getFinanceUserId())));
|
||||
// 2. 开始拼接
|
||||
return BeanUtils.toBean(pageResult, ErpFinanceReceiptRespVO.class, receipt -> {
|
||||
receipt.setItems(BeanUtils.toBean(financeReceiptItemMap.get(receipt.getId()), ErpFinanceReceiptRespVO.Item.class));
|
||||
MapUtils.findAndThen(customerMap, receipt.getCustomerId(), customer -> receipt.setCustomerName(customer.getName()));
|
||||
MapUtils.findAndThen(accountMap, receipt.getAccountId(), account -> receipt.setAccountName(account.getName()));
|
||||
MapUtils.findAndThen(userMap, Long.parseLong(receipt.getCreator()), user -> receipt.setCreatorName(user.getNickname()));
|
||||
MapUtils.findAndThen(userMap, receipt.getFinanceUserId(), user -> receipt.setFinanceUserName(user.getNickname()));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -17,7 +17,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
|
||||
@ToString(callSuper = true)
|
||||
public class ErpFinancePaymentPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "采购单编号", example = "XS001")
|
||||
@Schema(description = "付款单编号", example = "XS001")
|
||||
private String no;
|
||||
|
||||
@Schema(description = "付款时间")
|
||||
|
@ -79,10 +79,10 @@ public class ErpFinancePaymentRespVO {
|
||||
@Schema(description = "业务单号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756")
|
||||
private String bizNo;
|
||||
|
||||
@Schema(description = "应付欠款,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10000")
|
||||
@Schema(description = "应付金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10000")
|
||||
private BigDecimal totalPrice;
|
||||
|
||||
@Schema(description = "已付欠款,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10000")
|
||||
@Schema(description = "已付金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10000")
|
||||
private BigDecimal paidPrice;
|
||||
|
||||
@Schema(description = "本次付款,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10000")
|
||||
|
@ -58,8 +58,8 @@ public class ErpFinancePaymentSaveReqVO {
|
||||
@NotNull(message = "业务编号不能为空")
|
||||
private Long bizId;
|
||||
|
||||
@Schema(description = "已付欠款,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10000")
|
||||
@NotNull(message = "已付欠款不能为空")
|
||||
@Schema(description = "已付金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10000")
|
||||
@NotNull(message = "已付金额不能为空")
|
||||
private BigDecimal paidPrice;
|
||||
|
||||
@Schema(description = "本次付款,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10000")
|
||||
|
@ -0,0 +1,48 @@
|
||||
package cn.iocoder.yudao.module.erp.controller.admin.finance.vo.receipt;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - ERP 收款单分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class ErpFinanceReceiptPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "收款单编号", example = "XS001")
|
||||
private String no;
|
||||
|
||||
@Schema(description = "收款时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] receiptTime;
|
||||
|
||||
@Schema(description = "客户编号", example = "1724")
|
||||
private Long customerId;
|
||||
|
||||
@Schema(description = "创建者", example = "666")
|
||||
private String creator;
|
||||
|
||||
@Schema(description = "财务人员编号", example = "888")
|
||||
private String financeUserId;
|
||||
|
||||
@Schema(description = "收款账户编号", example = "31189")
|
||||
private Long accountId;
|
||||
|
||||
@Schema(description = "收款状态", example = "2")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "备注", example = "你猜")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "业务编号", example = "123")
|
||||
private String bizNo;
|
||||
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
package cn.iocoder.yudao.module.erp.controller.admin.finance.vo.receipt;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - ERP 收款单 Response VO")
|
||||
@Data
|
||||
public class ErpFinanceReceiptRespVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23752")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "收款单号", requiredMode = Schema.RequiredMode.REQUIRED, example = "FKD888")
|
||||
private String no;
|
||||
|
||||
@Schema(description = "收款状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "收款时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime receiptTime;
|
||||
|
||||
@Schema(description = "财务人员编号", example = "19690")
|
||||
private Long financeUserId;
|
||||
@Schema(description = "财务人员名称", example = "张三")
|
||||
private String financeUserName;
|
||||
|
||||
@Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "29399")
|
||||
private Long customerId;
|
||||
@Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "小番茄公司")
|
||||
private String customerName;
|
||||
|
||||
@Schema(description = "收款账户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "28989")
|
||||
private Long accountId;
|
||||
@Schema(description = "收款账户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
|
||||
private String accountName;
|
||||
|
||||
@Schema(description = "合计价格,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "13832")
|
||||
private BigDecimal totalPrice;
|
||||
|
||||
@Schema(description = "优惠金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "11600")
|
||||
private BigDecimal discountPrice;
|
||||
|
||||
@Schema(description = "实际价格,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "10000")
|
||||
private BigDecimal receiptPrice;
|
||||
|
||||
@Schema(description = "备注", example = "你猜")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "创建人", example = "芋道")
|
||||
private String creator;
|
||||
@Schema(description = "创建人名称", example = "芋道")
|
||||
private String creatorName;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "收款项列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<Item> items;
|
||||
|
||||
@Data
|
||||
public static class Item {
|
||||
|
||||
@Schema(description = "收款项编号", example = "11756")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "业务类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer bizType;
|
||||
|
||||
@Schema(description = "业务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756")
|
||||
private Long bizId;
|
||||
|
||||
@Schema(description = "业务单号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756")
|
||||
private String bizNo;
|
||||
|
||||
@Schema(description = "应收金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10000")
|
||||
private BigDecimal totalPrice;
|
||||
|
||||
@Schema(description = "已收金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10000")
|
||||
private BigDecimal receiptedPrice;
|
||||
|
||||
@Schema(description = "本次收款,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10000")
|
||||
@NotNull(message = "本次收款不能为空")
|
||||
private BigDecimal receiptPrice;
|
||||
|
||||
@Schema(description = "备注", example = "随便")
|
||||
private String remark;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
package cn.iocoder.yudao.module.erp.controller.admin.finance.vo.receipt;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - ERP 收款单新增/修改 Request VO")
|
||||
@Data
|
||||
public class ErpFinanceReceiptSaveReqVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23752")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "收款时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "收款时间不能为空")
|
||||
private LocalDateTime receiptTime;
|
||||
|
||||
@Schema(description = "财务人员编号", example = "19690")
|
||||
private Long financeUserId;
|
||||
|
||||
@Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "29399")
|
||||
@NotNull(message = "客户编号不能为空")
|
||||
private Long customerId;
|
||||
|
||||
@Schema(description = "收款账户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "28989")
|
||||
@NotNull(message = "收款账户编号不能为空")
|
||||
private Long accountId;
|
||||
|
||||
@Schema(description = "优惠金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "11600")
|
||||
@NotNull(message = "优惠金额不能为空")
|
||||
private BigDecimal discountPrice;
|
||||
|
||||
@Schema(description = "备注", example = "你猜")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "收款项列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotEmpty(message = "收款项列表不能为空")
|
||||
@Valid
|
||||
private List<Item> items;
|
||||
|
||||
@Data
|
||||
public static class Item {
|
||||
|
||||
@Schema(description = "收款项编号", example = "11756")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "业务类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "业务类型不能为空")
|
||||
private Integer bizType;
|
||||
|
||||
@Schema(description = "业务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756")
|
||||
@NotNull(message = "业务编号不能为空")
|
||||
private Long bizId;
|
||||
|
||||
@Schema(description = "已收金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10000")
|
||||
@NotNull(message = "已收金额不能为空")
|
||||
private BigDecimal receiptedPrice;
|
||||
|
||||
@Schema(description = "本次收款,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10000")
|
||||
@NotNull(message = "本次收款不能为空")
|
||||
private BigDecimal receiptPrice;
|
||||
|
||||
@Schema(description = "备注", example = "随便")
|
||||
private String remark;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -17,6 +17,10 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
|
||||
@ToString(callSuper = true)
|
||||
public class ErpSaleOutPageReqVO extends PageParam {
|
||||
|
||||
public static final Integer RECEIPT_STATUS_NONE = 0;
|
||||
public static final Integer RECEIPT_STATUS_PART = 1;
|
||||
public static final Integer RECEIPT_STATUS_ALL = 2;
|
||||
|
||||
@Schema(description = "销售单编号", example = "XS001")
|
||||
private String no;
|
||||
|
||||
@ -45,8 +49,11 @@ public class ErpSaleOutPageReqVO extends PageParam {
|
||||
@Schema(description = "结算账号编号", example = "1")
|
||||
private Long accountId;
|
||||
|
||||
@Schema(description = "是否欠款", example = "true")
|
||||
private Boolean debtStatus;
|
||||
@Schema(description = "收款状态", example = "1")
|
||||
private Integer receiptStatus;
|
||||
|
||||
@Schema(description = "是否可收款", example = "true")
|
||||
private Boolean receiptEnable; // 对应 receiptStatus = [0, 1]
|
||||
|
||||
@Schema(description = "销售单号", example = "1")
|
||||
private String orderNo;
|
||||
|
@ -55,6 +55,8 @@ public class ErpSaleOutRespVO {
|
||||
@Schema(description = "最终合计价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "24906")
|
||||
@ExcelProperty("最终合计价格")
|
||||
private BigDecimal totalPrice;
|
||||
@Schema(description = "已收款金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
|
||||
private BigDecimal receiptPrice;
|
||||
|
||||
@Schema(description = "合计产品价格,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
|
||||
private BigDecimal totalProductPrice;
|
||||
@ -68,15 +70,9 @@ public class ErpSaleOutRespVO {
|
||||
@Schema(description = "优惠金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
|
||||
private BigDecimal discountPrice;
|
||||
|
||||
@Schema(description = "定金金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
|
||||
@Schema(description = "其它金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
|
||||
private BigDecimal otherPrice;
|
||||
|
||||
@Schema(description = "本次收款,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
|
||||
private BigDecimal payPrice;
|
||||
@Schema(description = "本次欠款,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "666")
|
||||
private BigDecimal debtPrice;
|
||||
|
||||
|
||||
@Schema(description = "附件地址", example = "https://www.iocoder.cn")
|
||||
@ExcelProperty("附件地址")
|
||||
private String fileUrl;
|
||||
|
@ -35,10 +35,6 @@ public class ErpSaleOutSaveReqVO {
|
||||
@Schema(description = "其它金额,单位:元", example = "7127")
|
||||
private BigDecimal otherPrice;
|
||||
|
||||
@Schema(description = "本次收款,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
|
||||
@NotNull(message = "本次收款不能为空")
|
||||
private BigDecimal payPrice;
|
||||
|
||||
@Schema(description = "附件地址", example = "https://www.iocoder.cn")
|
||||
private String fileUrl;
|
||||
|
||||
|
@ -17,6 +17,10 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
|
||||
@ToString(callSuper = true)
|
||||
public class ErpSaleReturnPageReqVO extends PageParam {
|
||||
|
||||
public static final Integer REFUND_STATUS_NONE = 0;
|
||||
public static final Integer REFUND_STATUS_PART = 1;
|
||||
public static final Integer REFUND_STATUS_ALL = 2;
|
||||
|
||||
@Schema(description = "销售单编号", example = "XS001")
|
||||
private String no;
|
||||
|
||||
@ -48,4 +52,10 @@ public class ErpSaleReturnPageReqVO extends PageParam {
|
||||
@Schema(description = "销售单号", example = "1")
|
||||
private String orderNo;
|
||||
|
||||
@Schema(description = "退款状态", example = "1")
|
||||
private Integer refundStatus;
|
||||
|
||||
@Schema(description = "是否可退款", example = "true")
|
||||
private Boolean refundEnable; // 对应 refundStatus = [0, 1]
|
||||
|
||||
}
|
@ -55,6 +55,8 @@ public class ErpSaleReturnRespVO {
|
||||
@Schema(description = "最终合计价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "24906")
|
||||
@ExcelProperty("最终合计价格")
|
||||
private BigDecimal totalPrice;
|
||||
@Schema(description = "已退款金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
|
||||
private BigDecimal refundPrice;
|
||||
|
||||
@Schema(description = "合计产品价格,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
|
||||
private BigDecimal totalProductPrice;
|
||||
@ -68,15 +70,9 @@ public class ErpSaleReturnRespVO {
|
||||
@Schema(description = "优惠金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
|
||||
private BigDecimal discountPrice;
|
||||
|
||||
@Schema(description = "定金金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
|
||||
@Schema(description = "其它金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
|
||||
private BigDecimal otherPrice;
|
||||
|
||||
@Schema(description = "本次退款,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
|
||||
private BigDecimal refundPrice;
|
||||
@Schema(description = "本次欠款,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "666")
|
||||
private BigDecimal debtPrice;
|
||||
|
||||
|
||||
@Schema(description = "附件地址", example = "https://www.iocoder.cn")
|
||||
@ExcelProperty("附件地址")
|
||||
private String fileUrl;
|
||||
|
@ -35,10 +35,6 @@ public class ErpSaleReturnSaveReqVO {
|
||||
@Schema(description = "其它金额,单位:元", example = "7127")
|
||||
private BigDecimal otherPrice;
|
||||
|
||||
@Schema(description = "本次退款,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
|
||||
@NotNull(message = "本次退款不能为空")
|
||||
private BigDecimal refundPrice;
|
||||
|
||||
@Schema(description = "附件地址", example = "https://www.iocoder.cn")
|
||||
private String fileUrl;
|
||||
|
||||
|
@ -56,11 +56,11 @@ public class ErpFinancePaymentItemDO extends BaseDO {
|
||||
private String bizNo;
|
||||
|
||||
/**
|
||||
* 应付欠款,单位:分
|
||||
* 应付金额,单位:分
|
||||
*/
|
||||
private BigDecimal totalPrice;
|
||||
/**
|
||||
* 已付欠款,单位:分
|
||||
* 已付金额,单位:分
|
||||
*/
|
||||
private BigDecimal paidPrice;
|
||||
/**
|
||||
|
@ -0,0 +1,86 @@
|
||||
package cn.iocoder.yudao.module.erp.dal.dataobject.finance;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* ERP 收款单 DO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName("erp_finance_receipt")
|
||||
@KeySequence("erp_finance_receipt_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ErpFinanceReceiptDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 收款单号
|
||||
*/
|
||||
private String no;
|
||||
/**
|
||||
* 收款状态
|
||||
*
|
||||
* 枚举 {@link cn.iocoder.yudao.module.erp.enums.ErpAuditStatus}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 收款时间
|
||||
*/
|
||||
private LocalDateTime receiptTime;
|
||||
/**
|
||||
* 财务人员编号
|
||||
*
|
||||
* 关联 AdminUserDO 的 id 字段
|
||||
*/
|
||||
private Long financeUserId;
|
||||
/**
|
||||
* 客户编号
|
||||
*
|
||||
* 关联 {@link ErpCustomerDO#getId()}
|
||||
*/
|
||||
private Long customerId;
|
||||
/**
|
||||
* 收款账户编号
|
||||
*
|
||||
* 关联 {@link ErpAccountDO#getId()}
|
||||
*/
|
||||
private Long accountId;
|
||||
|
||||
/**
|
||||
* 合计价格,单位:元
|
||||
*/
|
||||
private BigDecimal totalPrice;
|
||||
/**
|
||||
* 优惠金额,单位:元
|
||||
*/
|
||||
private BigDecimal discountPrice;
|
||||
/**
|
||||
* 实付金额,单位:分
|
||||
*
|
||||
* receiptPrice = totalPrice - discountPrice
|
||||
*/
|
||||
private BigDecimal receiptPrice;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
package cn.iocoder.yudao.module.erp.dal.dataobject.finance;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleOutDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* ERP 收款项 DO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName("erp_finance_receipt_item")
|
||||
@KeySequence("erp_finance_receipt_item_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ErpFinanceReceiptItemDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 入库项编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 收款单编号
|
||||
*
|
||||
* 关联 {@link ErpFinanceReceiptDO#getId()}
|
||||
*/
|
||||
private Long receiptId;
|
||||
|
||||
/**
|
||||
* 业务类型
|
||||
*
|
||||
* 枚举 {@link cn.iocoder.yudao.module.erp.enums.common.ErpBizTypeEnum} 的销售出库、退货
|
||||
*/
|
||||
private Integer bizType;
|
||||
/**
|
||||
* 业务编号
|
||||
*
|
||||
* 例如说:{@link ErpSaleOutDO#getId()}
|
||||
*/
|
||||
private Long bizId;
|
||||
/**
|
||||
* 业务单号
|
||||
*
|
||||
* 例如说:{@link ErpSaleOutDO#getNo()}
|
||||
*/
|
||||
private String bizNo;
|
||||
|
||||
/**
|
||||
* 应收金额,单位:分
|
||||
*/
|
||||
private BigDecimal totalPrice;
|
||||
/**
|
||||
* 已收金额,单位:分
|
||||
*/
|
||||
private BigDecimal receiptedPrice;
|
||||
/**
|
||||
* 本次收款,单位:分
|
||||
*/
|
||||
private BigDecimal receiptPrice;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
}
|
@ -83,7 +83,7 @@ public class ErpPurchaseInDO extends BaseDO {
|
||||
/**
|
||||
* 已支付金额,单位:元
|
||||
*
|
||||
* 目的:和 TODO erp_finance_payment 结合,记录已支付金额
|
||||
* 目的:和 {@link cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinancePaymentDO} 结合,记录已支付金额
|
||||
*/
|
||||
private BigDecimal paymentPrice;
|
||||
|
||||
|
@ -83,7 +83,7 @@ public class ErpPurchaseReturnDO extends BaseDO {
|
||||
/**
|
||||
* 已退款金额,单位:元
|
||||
*
|
||||
* 目的:和 TODO erp_finance_payment 结合,记录已退款金额
|
||||
* 目的:和 {@link cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinancePaymentDO} 结合,记录已支付金额
|
||||
*/
|
||||
private BigDecimal refundPrice;
|
||||
|
||||
|
@ -83,9 +83,15 @@ public class ErpSaleOutDO extends BaseDO {
|
||||
/**
|
||||
* 最终合计价格,单位:元
|
||||
*
|
||||
* totalPrice = totalProductPrice + totalTaxPrice - discountPrice
|
||||
* totalPrice = totalProductPrice + totalTaxPrice - discountPrice + otherPrice
|
||||
*/
|
||||
private BigDecimal totalPrice;
|
||||
/**
|
||||
* 已收款金额,单位:元
|
||||
*
|
||||
* 目的:和 {@link cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinanceReceiptDO} 结合,记录已收款金额
|
||||
*/
|
||||
private BigDecimal receiptPrice;
|
||||
|
||||
/**
|
||||
* 合计产品价格,单位:元
|
||||
@ -110,18 +116,6 @@ public class ErpSaleOutDO extends BaseDO {
|
||||
*/
|
||||
private BigDecimal otherPrice;
|
||||
|
||||
// TODO 芋艿:receiptPrice
|
||||
/**
|
||||
* 本次收款,单位:元
|
||||
*
|
||||
* payPrice = totalPrice + otherPrice - debtPrice
|
||||
*/
|
||||
private BigDecimal payPrice;
|
||||
/**
|
||||
* 本次欠款,单位:元
|
||||
*/
|
||||
private BigDecimal debtPrice;
|
||||
|
||||
/**
|
||||
* 附件地址
|
||||
*/
|
||||
|
@ -83,9 +83,15 @@ public class ErpSaleReturnDO extends BaseDO {
|
||||
/**
|
||||
* 最终合计价格,单位:元
|
||||
*
|
||||
* totalPrice = totalProductPrice + totalTaxPrice - discountPrice
|
||||
* totalPrice = totalProductPrice + totalTaxPrice - discountPrice + otherPrice
|
||||
*/
|
||||
private BigDecimal totalPrice;
|
||||
/**
|
||||
* 已退款金额,单位:元
|
||||
*
|
||||
* 目的:和 {@link cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinanceReceiptDO} 结合,记录已退款金额
|
||||
*/
|
||||
private BigDecimal refundPrice;
|
||||
|
||||
/**
|
||||
* 合计产品价格,单位:元
|
||||
@ -110,17 +116,6 @@ public class ErpSaleReturnDO extends BaseDO {
|
||||
*/
|
||||
private BigDecimal otherPrice;
|
||||
|
||||
/**
|
||||
* 本次收款,单位:元
|
||||
*
|
||||
* refundPrice = totalPrice + otherPrice - debtPrice
|
||||
*/
|
||||
private BigDecimal refundPrice;
|
||||
/**
|
||||
* 本次欠款,单位:元
|
||||
*/
|
||||
private BigDecimal debtPrice;
|
||||
|
||||
/**
|
||||
* 附件地址
|
||||
*/
|
||||
|
@ -0,0 +1,44 @@
|
||||
package cn.iocoder.yudao.module.erp.dal.mysql.finance;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinanceReceiptItemDO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* ERP 收款单项 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface ErpFinanceReceiptItemMapper extends BaseMapperX<ErpFinanceReceiptItemDO> {
|
||||
|
||||
default List<ErpFinanceReceiptItemDO> selectListByReceiptId(Long receiptId) {
|
||||
return selectList(ErpFinanceReceiptItemDO::getReceiptId, receiptId);
|
||||
}
|
||||
|
||||
default List<ErpFinanceReceiptItemDO> selectListByReceiptIds(Collection<Long> receiptIds) {
|
||||
return selectList(ErpFinanceReceiptItemDO::getReceiptId, receiptIds);
|
||||
}
|
||||
|
||||
default BigDecimal selectReceiptPriceSumByBizIdAndBizType(Long bizId, Integer bizType) {
|
||||
// SQL sum 查询
|
||||
List<Map<String, Object>> result = selectMaps(new QueryWrapper<ErpFinanceReceiptItemDO>()
|
||||
.select("SUM(receipt_price) AS receiptPriceSum")
|
||||
.eq("biz_id", bizId)
|
||||
.eq("biz_type", bizType));
|
||||
// 获得数量
|
||||
if (CollUtil.isEmpty(result)) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
return BigDecimal.valueOf(MapUtil.getDouble(result.get(0), "receiptPriceSum", 0D));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package cn.iocoder.yudao.module.erp.dal.mysql.finance;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
|
||||
import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.receipt.ErpFinanceReceiptPageReqVO;
|
||||
import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinanceReceiptDO;
|
||||
import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinanceReceiptItemDO;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* ERP 收款单 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface ErpFinanceReceiptMapper extends BaseMapperX<ErpFinanceReceiptDO> {
|
||||
|
||||
default PageResult<ErpFinanceReceiptDO> selectPage(ErpFinanceReceiptPageReqVO reqVO) {
|
||||
MPJLambdaWrapperX<ErpFinanceReceiptDO> query = new MPJLambdaWrapperX<ErpFinanceReceiptDO>()
|
||||
.likeIfPresent(ErpFinanceReceiptDO::getNo, reqVO.getNo())
|
||||
.betweenIfPresent(ErpFinanceReceiptDO::getReceiptTime, reqVO.getReceiptTime())
|
||||
.eqIfPresent(ErpFinanceReceiptDO::getCustomerId, reqVO.getCustomerId())
|
||||
.eqIfPresent(ErpFinanceReceiptDO::getCreator, reqVO.getCreator())
|
||||
.eqIfPresent(ErpFinanceReceiptDO::getFinanceUserId, reqVO.getFinanceUserId())
|
||||
.eqIfPresent(ErpFinanceReceiptDO::getAccountId, reqVO.getAccountId())
|
||||
.eqIfPresent(ErpFinanceReceiptDO::getStatus, reqVO.getStatus())
|
||||
.likeIfPresent(ErpFinanceReceiptDO::getRemark, reqVO.getRemark())
|
||||
.orderByDesc(ErpFinanceReceiptDO::getId);
|
||||
if (reqVO.getBizNo() != null) {
|
||||
query.leftJoin(ErpFinanceReceiptItemDO.class, ErpFinanceReceiptItemDO::getReceiptId, ErpFinanceReceiptDO::getId)
|
||||
.eq(reqVO.getBizNo() != null, ErpFinanceReceiptItemDO::getBizNo, reqVO.getBizNo())
|
||||
.groupBy(ErpFinanceReceiptDO::getId); // 避免 1 对多查询,产生相同的 1
|
||||
}
|
||||
return selectJoinPage(reqVO, ErpFinanceReceiptDO.class, query);
|
||||
}
|
||||
|
||||
default int updateByIdAndStatus(Long id, Integer status, ErpFinanceReceiptDO updateObj) {
|
||||
return update(updateObj, new LambdaUpdateWrapper<ErpFinanceReceiptDO>()
|
||||
.eq(ErpFinanceReceiptDO::getId, id).eq(ErpFinanceReceiptDO::getStatus, status));
|
||||
}
|
||||
|
||||
default ErpFinanceReceiptDO selectByNo(String no) {
|
||||
return selectOne(ErpFinanceReceiptDO::getNo, no);
|
||||
}
|
||||
|
||||
}
|
@ -7,11 +7,12 @@ import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
|
||||
import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.out.ErpSaleOutPageReqVO;
|
||||
import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleOutDO;
|
||||
import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleOutItemDO;
|
||||
import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* ERP 销售出库 Mapper
|
||||
@ -32,10 +33,17 @@ public interface ErpSaleOutMapper extends BaseMapperX<ErpSaleOutDO> {
|
||||
.eqIfPresent(ErpSaleOutDO::getAccountId, reqVO.getAccountId())
|
||||
.likeIfPresent(ErpSaleOutDO::getOrderNo, reqVO.getOrderNo())
|
||||
.orderByDesc(ErpSaleOutDO::getId);
|
||||
if (Boolean.TRUE.equals(reqVO.getDebtStatus())) {
|
||||
query.gt(ErpSaleOutDO::getDebtPrice, BigDecimal.ZERO);
|
||||
} else if (Boolean.FALSE.equals(reqVO.getDebtStatus())) {
|
||||
query.eq(ErpSaleOutDO::getDebtPrice, BigDecimal.ZERO);
|
||||
// 收款状态。为什么需要 t. 的原因,是因为联表查询时,需要指定表名,不然会报字段不存在的错误
|
||||
if (Objects.equals(reqVO.getReceiptStatus(), ErpSaleOutPageReqVO.RECEIPT_STATUS_NONE)) {
|
||||
query.eq(ErpSaleOutDO::getReceiptPrice, 0);
|
||||
} else if (Objects.equals(reqVO.getReceiptStatus(), ErpSaleOutPageReqVO.RECEIPT_STATUS_PART)) {
|
||||
query.gt(ErpSaleOutDO::getReceiptPrice, 0).apply("t.receipt_price < t.total_price");
|
||||
} else if (Objects.equals(reqVO.getReceiptStatus(), ErpSaleOutPageReqVO.RECEIPT_STATUS_ALL)) {
|
||||
query.apply("t.receipt_price = t.total_price");
|
||||
}
|
||||
if (Boolean.TRUE.equals(reqVO.getReceiptEnable())) {
|
||||
query.eq(ErpSaleOutDO::getStatus, ErpAuditStatus.APPROVE.getStatus())
|
||||
.apply("t.receipt_price < t.total_price");
|
||||
}
|
||||
if (reqVO.getWarehouseId() != null || reqVO.getProductId() != null) {
|
||||
query.leftJoin(ErpSaleOutItemDO.class, ErpSaleOutItemDO::getOutId, ErpSaleOutDO::getId)
|
||||
|
@ -5,12 +5,15 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
|
||||
import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.returns.ErpSaleReturnPageReqVO;
|
||||
import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleOutDO;
|
||||
import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleReturnDO;
|
||||
import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleReturnItemDO;
|
||||
import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* ERP 销售退货 Mapper
|
||||
@ -31,6 +34,18 @@ public interface ErpSaleReturnMapper extends BaseMapperX<ErpSaleReturnDO> {
|
||||
.eqIfPresent(ErpSaleReturnDO::getAccountId, reqVO.getAccountId())
|
||||
.likeIfPresent(ErpSaleReturnDO::getOrderNo, reqVO.getOrderNo())
|
||||
.orderByDesc(ErpSaleReturnDO::getId);
|
||||
// 退款状态。为什么需要 t. 的原因,是因为联表查询时,需要指定表名,不然会报字段不存在的错误
|
||||
if (Objects.equals(reqVO.getRefundStatus(), ErpSaleReturnPageReqVO.REFUND_STATUS_NONE)) {
|
||||
query.eq(ErpSaleReturnDO::getRefundPrice, 0);
|
||||
} else if (Objects.equals(reqVO.getRefundStatus(), ErpSaleReturnPageReqVO.REFUND_STATUS_PART)) {
|
||||
query.gt(ErpSaleReturnDO::getRefundPrice, 0).apply("t.refund_price < t.total_price");
|
||||
} else if (Objects.equals(reqVO.getRefundStatus(), ErpSaleReturnPageReqVO.REFUND_STATUS_ALL)) {
|
||||
query.apply("t.refund_price = t.total_price");
|
||||
}
|
||||
if (Boolean.TRUE.equals(reqVO.getRefundEnable())) {
|
||||
query.eq(ErpSaleOutDO::getStatus, ErpAuditStatus.APPROVE.getStatus())
|
||||
.apply("t.refund_price < t.total_price");
|
||||
}
|
||||
if (reqVO.getWarehouseId() != null || reqVO.getProductId() != null) {
|
||||
query.leftJoin(ErpSaleReturnItemDO.class, ErpSaleReturnItemDO::getReturnId, ErpSaleReturnDO::getId)
|
||||
.eq(reqVO.getWarehouseId() != null, ErpSaleReturnItemDO::getWarehouseId, reqVO.getWarehouseId())
|
||||
|
@ -68,6 +68,10 @@ public class ErpNoRedisDAO {
|
||||
* 付款单 {@link cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinancePaymentDO}
|
||||
*/
|
||||
public static final String FINANCE_PAYMENT_NO_PREFIX = "FKD";
|
||||
/**
|
||||
* 收款单 {@link cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinanceReceiptDO}
|
||||
*/
|
||||
public static final String FINANCE_RECEIPT_NO_PREFIX = "SKD";
|
||||
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
@ -96,6 +96,9 @@ public class ErpFinancePaymentServiceImpl implements ErpFinancePaymentService {
|
||||
// 2.2 插入付款单项
|
||||
paymentItems.forEach(o -> o.setPaymentId(payment.getId()));
|
||||
financePaymentItemMapper.insertBatch(paymentItems);
|
||||
|
||||
// 3. 更新采购入库、退货的付款金额情况
|
||||
updatePurchasePrice(paymentItems);
|
||||
return payment.getId();
|
||||
}
|
||||
|
||||
@ -127,9 +130,6 @@ public class ErpFinancePaymentServiceImpl implements ErpFinancePaymentService {
|
||||
financePaymentMapper.updateById(updateObj);
|
||||
// 2.2 更新付款单项
|
||||
updateFinancePaymentItemList(updateReqVO.getId(), paymentItems);
|
||||
|
||||
// 3. 更新采购入库、退货的付款金额情况
|
||||
updatePurchasePrice(paymentItems);
|
||||
}
|
||||
|
||||
private void calculateTotalPrice(ErpFinancePaymentDO payment, List<ErpFinancePaymentItemDO> paymentItems) {
|
||||
|
@ -0,0 +1,84 @@
|
||||
package cn.iocoder.yudao.module.erp.service.finance;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.receipt.ErpFinanceReceiptPageReqVO;
|
||||
import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.receipt.ErpFinanceReceiptSaveReqVO;
|
||||
import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinanceReceiptDO;
|
||||
import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinanceReceiptItemDO;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ERP 收款单 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface ErpFinanceReceiptService {
|
||||
|
||||
/**
|
||||
* 创建收款单
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createFinanceReceipt(@Valid ErpFinanceReceiptSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新收款单
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateFinanceReceipt(@Valid ErpFinanceReceiptSaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 更新收款单的状态
|
||||
*
|
||||
* @param id 编号
|
||||
* @param status 状态
|
||||
*/
|
||||
void updateFinanceReceiptStatus(Long id, Integer status);
|
||||
|
||||
/**
|
||||
* 删除收款单
|
||||
*
|
||||
* @param ids 编号数组
|
||||
*/
|
||||
void deleteFinanceReceipt(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 获得收款单
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 收款单
|
||||
*/
|
||||
ErpFinanceReceiptDO getFinanceReceipt(Long id);
|
||||
|
||||
/**
|
||||
* 获得收款单分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 收款单分页
|
||||
*/
|
||||
PageResult<ErpFinanceReceiptDO> getFinanceReceiptPage(ErpFinanceReceiptPageReqVO pageReqVO);
|
||||
|
||||
// ==================== 收款单项 ====================
|
||||
|
||||
/**
|
||||
* 获得收款单项列表
|
||||
*
|
||||
* @param receiptId 收款单编号
|
||||
* @return 收款单项列表
|
||||
*/
|
||||
List<ErpFinanceReceiptItemDO> getFinanceReceiptItemListByReceiptId(Long receiptId);
|
||||
|
||||
/**
|
||||
* 获得收款单项 List
|
||||
*
|
||||
* @param receiptIds 收款单编号数组
|
||||
* @return 收款单项 List
|
||||
*/
|
||||
List<ErpFinanceReceiptItemDO> getFinanceReceiptItemListByReceiptIds(Collection<Long> receiptIds);
|
||||
|
||||
}
|
@ -0,0 +1,273 @@
|
||||
package cn.iocoder.yudao.module.erp.service.finance;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.receipt.ErpFinanceReceiptPageReqVO;
|
||||
import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.receipt.ErpFinanceReceiptSaveReqVO;
|
||||
import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinanceReceiptDO;
|
||||
import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinanceReceiptItemDO;
|
||||
import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleOutDO;
|
||||
import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleReturnDO;
|
||||
import cn.iocoder.yudao.module.erp.dal.mysql.finance.ErpFinanceReceiptItemMapper;
|
||||
import cn.iocoder.yudao.module.erp.dal.mysql.finance.ErpFinanceReceiptMapper;
|
||||
import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO;
|
||||
import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
|
||||
import cn.iocoder.yudao.module.erp.enums.common.ErpBizTypeEnum;
|
||||
import cn.iocoder.yudao.module.erp.service.sale.ErpCustomerService;
|
||||
import cn.iocoder.yudao.module.erp.service.sale.ErpSaleOutService;
|
||||
import cn.iocoder.yudao.module.erp.service.sale.ErpSaleReturnService;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
||||
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
|
||||
|
||||
// TODO 芋艿:记录操作日志
|
||||
|
||||
/**
|
||||
* ERP 收款单 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class ErpFinanceReceiptServiceImpl implements ErpFinanceReceiptService {
|
||||
|
||||
@Resource
|
||||
private ErpFinanceReceiptMapper financeReceiptMapper;
|
||||
@Resource
|
||||
private ErpFinanceReceiptItemMapper financeReceiptItemMapper;
|
||||
|
||||
@Resource
|
||||
private ErpNoRedisDAO noRedisDAO;
|
||||
|
||||
@Resource
|
||||
private ErpCustomerService customerService;
|
||||
@Resource
|
||||
private ErpAccountService accountService;
|
||||
@Resource
|
||||
private ErpSaleOutService saleOutService;
|
||||
@Resource
|
||||
private ErpSaleReturnService saleReturnService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long createFinanceReceipt(ErpFinanceReceiptSaveReqVO createReqVO) {
|
||||
// 1.1 校验订单项的有效性
|
||||
List<ErpFinanceReceiptItemDO> receiptItems = validateFinanceReceiptItems(
|
||||
createReqVO.getCustomerId(), createReqVO.getItems());
|
||||
// 1.2 校验客户
|
||||
customerService.validateCustomer(createReqVO.getCustomerId());
|
||||
// 1.3 校验结算账户
|
||||
if (createReqVO.getAccountId() != null) {
|
||||
accountService.validateAccount(createReqVO.getAccountId());
|
||||
}
|
||||
// 1.4 校验财务人员
|
||||
if (createReqVO.getFinanceUserId() != null) {
|
||||
adminUserApi.validateUser(createReqVO.getFinanceUserId());
|
||||
}
|
||||
// 1.5 生成收款单号,并校验唯一性
|
||||
String no = noRedisDAO.generate(ErpNoRedisDAO.FINANCE_RECEIPT_NO_PREFIX);
|
||||
if (financeReceiptMapper.selectByNo(no) != null) {
|
||||
throw exception(FINANCE_RECEIPT_NO_EXISTS);
|
||||
}
|
||||
|
||||
// 2.1 插入收款单
|
||||
ErpFinanceReceiptDO receipt = BeanUtils.toBean(createReqVO, ErpFinanceReceiptDO.class, in -> in
|
||||
.setNo(no).setStatus(ErpAuditStatus.PROCESS.getStatus()));
|
||||
calculateTotalPrice(receipt, receiptItems);
|
||||
financeReceiptMapper.insert(receipt);
|
||||
// 2.2 插入收款单项
|
||||
receiptItems.forEach(o -> o.setReceiptId(receipt.getId()));
|
||||
financeReceiptItemMapper.insertBatch(receiptItems);
|
||||
|
||||
// 3. 更新销售出库、退货的收款金额情况
|
||||
updateSalePrice(receiptItems);
|
||||
return receipt.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateFinanceReceipt(ErpFinanceReceiptSaveReqVO updateReqVO) {
|
||||
// 1.1 校验存在
|
||||
ErpFinanceReceiptDO receipt = validateFinanceReceiptExists(updateReqVO.getId());
|
||||
if (ErpAuditStatus.APPROVE.getStatus().equals(receipt.getStatus())) {
|
||||
throw exception(FINANCE_RECEIPT_UPDATE_FAIL_APPROVE, receipt.getNo());
|
||||
}
|
||||
// 1.2 校验客户
|
||||
customerService.validateCustomer(updateReqVO.getCustomerId());
|
||||
// 1.3 校验结算账户
|
||||
if (updateReqVO.getAccountId() != null) {
|
||||
accountService.validateAccount(updateReqVO.getAccountId());
|
||||
}
|
||||
// 1.4 校验财务人员
|
||||
if (updateReqVO.getFinanceUserId() != null) {
|
||||
adminUserApi.validateUser(updateReqVO.getFinanceUserId());
|
||||
}
|
||||
// 1.5 校验收款单项的有效性
|
||||
List<ErpFinanceReceiptItemDO> receiptItems = validateFinanceReceiptItems(
|
||||
updateReqVO.getCustomerId(), updateReqVO.getItems());
|
||||
|
||||
// 2.1 更新收款单
|
||||
ErpFinanceReceiptDO updateObj = BeanUtils.toBean(updateReqVO, ErpFinanceReceiptDO.class);
|
||||
calculateTotalPrice(updateObj, receiptItems);
|
||||
financeReceiptMapper.updateById(updateObj);
|
||||
// 2.2 更新收款单项
|
||||
updateFinanceReceiptItemList(updateReqVO.getId(), receiptItems);
|
||||
}
|
||||
|
||||
private void calculateTotalPrice(ErpFinanceReceiptDO receipt, List<ErpFinanceReceiptItemDO> receiptItems) {
|
||||
receipt.setTotalPrice(getSumValue(receiptItems, ErpFinanceReceiptItemDO::getReceiptPrice, BigDecimal::add, BigDecimal.ZERO));
|
||||
receipt.setReceiptPrice(receipt.getTotalPrice().subtract(receipt.getDiscountPrice()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateFinanceReceiptStatus(Long id, Integer status) {
|
||||
boolean approve = ErpAuditStatus.APPROVE.getStatus().equals(status);
|
||||
// 1.1 校验存在
|
||||
ErpFinanceReceiptDO receipt = validateFinanceReceiptExists(id);
|
||||
// 1.2 校验状态
|
||||
if (receipt.getStatus().equals(status)) {
|
||||
throw exception(approve ? FINANCE_RECEIPT_APPROVE_FAIL : FINANCE_RECEIPT_PROCESS_FAIL);
|
||||
}
|
||||
|
||||
// 2. 更新状态
|
||||
int updateCount = financeReceiptMapper.updateByIdAndStatus(id, receipt.getStatus(),
|
||||
new ErpFinanceReceiptDO().setStatus(status));
|
||||
if (updateCount == 0) {
|
||||
throw exception(approve ? FINANCE_RECEIPT_APPROVE_FAIL : FINANCE_RECEIPT_PROCESS_FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
private List<ErpFinanceReceiptItemDO> validateFinanceReceiptItems(
|
||||
Long customerId,
|
||||
List<ErpFinanceReceiptSaveReqVO.Item> list) {
|
||||
return convertList(list, o -> BeanUtils.toBean(o, ErpFinanceReceiptItemDO.class, item -> {
|
||||
if (ObjectUtil.equal(item.getBizType(), ErpBizTypeEnum.SALE_OUT.getType())) {
|
||||
ErpSaleOutDO saleOut = saleOutService.validateSaleOut(item.getBizId());
|
||||
Assert.equals(saleOut.getCustomerId(), customerId, "客户必须相同");
|
||||
item.setTotalPrice(saleOut.getTotalPrice()).setBizNo(saleOut.getNo());
|
||||
} else if (ObjectUtil.equal(item.getBizType(), ErpBizTypeEnum.SALE_RETURN.getType())) {
|
||||
ErpSaleReturnDO saleReturn = saleReturnService.validateSaleReturn(item.getBizId());
|
||||
Assert.equals(saleReturn.getCustomerId(), customerId, "客户必须相同");
|
||||
item.setTotalPrice(saleReturn.getTotalPrice().negate()).setBizNo(saleReturn.getNo());
|
||||
} else {
|
||||
throw new IllegalArgumentException("业务类型不正确:" + item.getBizType());
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private void updateFinanceReceiptItemList(Long id, List<ErpFinanceReceiptItemDO> newList) {
|
||||
// 第一步,对比新老数据,获得添加、修改、删除的列表
|
||||
List<ErpFinanceReceiptItemDO> oldList = financeReceiptItemMapper.selectListByReceiptId(id);
|
||||
List<List<ErpFinanceReceiptItemDO>> diffList = diffList(oldList, newList, // id 不同,就认为是不同的记录
|
||||
(oldVal, newVal) -> oldVal.getId().equals(newVal.getId()));
|
||||
|
||||
// 第二步,批量添加、修改、删除
|
||||
if (CollUtil.isNotEmpty(diffList.get(0))) {
|
||||
diffList.get(0).forEach(o -> o.setReceiptId(id));
|
||||
financeReceiptItemMapper.insertBatch(diffList.get(0));
|
||||
}
|
||||
if (CollUtil.isNotEmpty(diffList.get(1))) {
|
||||
financeReceiptItemMapper.updateBatch(diffList.get(1));
|
||||
}
|
||||
if (CollUtil.isNotEmpty(diffList.get(2))) {
|
||||
financeReceiptItemMapper.deleteBatchIds(convertList(diffList.get(2), ErpFinanceReceiptItemDO::getId));
|
||||
}
|
||||
|
||||
// 第三步,更新销售出库、退货的收款金额情况
|
||||
updateSalePrice(CollectionUtils.newArrayList(diffList));
|
||||
}
|
||||
|
||||
private void updateSalePrice(List<ErpFinanceReceiptItemDO> receiptItems) {
|
||||
receiptItems.forEach(receiptItem -> {
|
||||
BigDecimal totalReceiptPrice = financeReceiptItemMapper.selectReceiptPriceSumByBizIdAndBizType(
|
||||
receiptItem.getBizId(), receiptItem.getBizType());
|
||||
if (ErpBizTypeEnum.SALE_OUT.getType().equals(receiptItem.getBizType())) {
|
||||
saleOutService.updateSaleInReceiptPrice(receiptItem.getBizId(), totalReceiptPrice);
|
||||
} else if (ErpBizTypeEnum.SALE_RETURN.getType().equals(receiptItem.getBizType())) {
|
||||
saleReturnService.updateSaleReturnRefundPrice(receiptItem.getBizId(), totalReceiptPrice.negate());
|
||||
} else {
|
||||
throw new IllegalArgumentException("业务类型不正确:" + receiptItem.getBizType());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteFinanceReceipt(List<Long> ids) {
|
||||
// 1. 校验不处于已审批
|
||||
List<ErpFinanceReceiptDO> receipts = financeReceiptMapper.selectBatchIds(ids);
|
||||
if (CollUtil.isEmpty(receipts)) {
|
||||
return;
|
||||
}
|
||||
receipts.forEach(receipt -> {
|
||||
if (ErpAuditStatus.APPROVE.getStatus().equals(receipt.getStatus())) {
|
||||
throw exception(FINANCE_RECEIPT_DELETE_FAIL_APPROVE, receipt.getNo());
|
||||
}
|
||||
});
|
||||
|
||||
// 2. 遍历删除,并记录操作日志
|
||||
receipts.forEach(receipt -> {
|
||||
// 2.1 删除收款单
|
||||
financeReceiptMapper.deleteById(receipt.getId());
|
||||
// 2.2 删除收款单项
|
||||
List<ErpFinanceReceiptItemDO> receiptItems = financeReceiptItemMapper.selectListByReceiptId(receipt.getId());
|
||||
financeReceiptItemMapper.deleteBatchIds(convertSet(receiptItems, ErpFinanceReceiptItemDO::getId));
|
||||
|
||||
// 2.3 更新销售出库、退货的收款金额情况
|
||||
updateSalePrice(receiptItems);
|
||||
});
|
||||
}
|
||||
|
||||
private ErpFinanceReceiptDO validateFinanceReceiptExists(Long id) {
|
||||
ErpFinanceReceiptDO receipt = financeReceiptMapper.selectById(id);
|
||||
if (receipt == null) {
|
||||
throw exception(FINANCE_RECEIPT_NOT_EXISTS);
|
||||
}
|
||||
return receipt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErpFinanceReceiptDO getFinanceReceipt(Long id) {
|
||||
return financeReceiptMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<ErpFinanceReceiptDO> getFinanceReceiptPage(ErpFinanceReceiptPageReqVO pageReqVO) {
|
||||
return financeReceiptMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
// ==================== 收款单项 ====================
|
||||
|
||||
@Override
|
||||
public List<ErpFinanceReceiptItemDO> getFinanceReceiptItemListByReceiptId(Long receiptId) {
|
||||
return financeReceiptItemMapper.selectListByReceiptId(receiptId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ErpFinanceReceiptItemDO> getFinanceReceiptItemListByReceiptIds(Collection<Long> receiptIds) {
|
||||
if (CollUtil.isEmpty(receiptIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return financeReceiptItemMapper.selectListByReceiptIds(receiptIds);
|
||||
}
|
||||
|
||||
}
|
@ -194,7 +194,7 @@ public class ErpPurchaseInServiceImpl implements ErpPurchaseInService {
|
||||
return;
|
||||
}
|
||||
if (paymentPrice.compareTo(purchaseIn.getTotalPrice()) > 0) {
|
||||
throw exception(PURCHASE_IN_FAIL_PAYMENT_PRICE_EXCEED, purchaseIn.getTotalPrice(), paymentPrice);
|
||||
throw exception(PURCHASE_IN_FAIL_PAYMENT_PRICE_EXCEED, paymentPrice, purchaseIn.getTotalPrice());
|
||||
}
|
||||
purchaseInMapper.updateById(new ErpPurchaseInDO().setId(id).setPaymentPrice(paymentPrice));
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ public class ErpPurchaseReturnServiceImpl implements ErpPurchaseReturnService {
|
||||
return;
|
||||
}
|
||||
if (refundPrice.compareTo(purchaseReturn.getTotalPrice()) > 0) {
|
||||
throw exception(PURCHASE_RETURN_FAIL_REFUND_PRICE_EXCEED, purchaseReturn.getTotalPrice(), refundPrice);
|
||||
throw exception(PURCHASE_RETURN_FAIL_REFUND_PRICE_EXCEED, refundPrice, purchaseReturn.getTotalPrice());
|
||||
}
|
||||
purchaseReturnMapper.updateById(new ErpPurchaseReturnDO().setId(id).setRefundPrice(refundPrice));
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleOutDO;
|
||||
import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleOutItemDO;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@ -40,6 +41,14 @@ public interface ErpSaleOutService {
|
||||
*/
|
||||
void updateSaleOutStatus(Long id, Integer status);
|
||||
|
||||
/**
|
||||
* 更新销售出库的收款金额
|
||||
*
|
||||
* @param id 编号
|
||||
* @param receiptPrice 收款金额
|
||||
*/
|
||||
void updateSaleInReceiptPrice(Long id, BigDecimal receiptPrice);
|
||||
|
||||
/**
|
||||
* 删除销售出库
|
||||
*
|
||||
@ -55,6 +64,14 @@ public interface ErpSaleOutService {
|
||||
*/
|
||||
ErpSaleOutDO getSaleOut(Long id);
|
||||
|
||||
/**
|
||||
* 校验销售出库,已经审核通过
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 销售出库
|
||||
*/
|
||||
ErpSaleOutDO validateSaleOut(Long id);
|
||||
|
||||
/**
|
||||
* 获得销售出库分页
|
||||
*
|
||||
@ -81,4 +98,5 @@ public interface ErpSaleOutService {
|
||||
*/
|
||||
List<ErpSaleOutItemDO> getSaleOutItemListByOutIds(Collection<Long> outIds);
|
||||
|
||||
|
||||
}
|
@ -148,10 +148,7 @@ public class ErpSaleOutServiceImpl implements ErpSaleOutService {
|
||||
saleOut.setDiscountPercent(BigDecimal.ZERO);
|
||||
}
|
||||
saleOut.setDiscountPrice(MoneyUtils.priceMultiplyPercent(saleOut.getTotalPrice(), saleOut.getDiscountPercent()));
|
||||
saleOut.setTotalPrice(saleOut.getTotalPrice().subtract(saleOut.getDiscountPrice()));
|
||||
// 计算应收金额
|
||||
BigDecimal allPrice = saleOut.getTotalPrice().add(saleOut.getOtherPrice());
|
||||
saleOut.setDebtPrice(allPrice.subtract(saleOut.getPayPrice()));
|
||||
saleOut.setTotalPrice(saleOut.getTotalPrice().subtract(saleOut.getDiscountPrice().add(saleOut.getOtherPrice())));
|
||||
}
|
||||
|
||||
private void updateSaleOrderOutCount(Long orderId) {
|
||||
@ -174,6 +171,10 @@ public class ErpSaleOutServiceImpl implements ErpSaleOutService {
|
||||
if (saleOut.getStatus().equals(status)) {
|
||||
throw exception(approve ? SALE_OUT_APPROVE_FAIL : SALE_OUT_PROCESS_FAIL);
|
||||
}
|
||||
// 1.3 校验已退款
|
||||
if (approve && saleOut.getReceiptPrice().compareTo(BigDecimal.ZERO) > 0) {
|
||||
throw exception(SALE_OUT_PROCESS_FAIL_EXISTS_RECEIPT);
|
||||
}
|
||||
|
||||
// 2. 更新状态
|
||||
int updateCount = saleOutMapper.updateByIdAndStatus(id, saleOut.getStatus(),
|
||||
@ -194,6 +195,18 @@ public class ErpSaleOutServiceImpl implements ErpSaleOutService {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSaleInReceiptPrice(Long id, BigDecimal receiptPrice) {
|
||||
ErpSaleOutDO saleOut = saleOutMapper.selectById(id);
|
||||
if (saleOut.getReceiptPrice().equals(receiptPrice)) {
|
||||
return;
|
||||
}
|
||||
if (receiptPrice.compareTo(saleOut.getTotalPrice()) > 0) {
|
||||
throw exception(SALE_OUT_FAIL_RECEIPT_PRICE_EXCEED, receiptPrice, saleOut.getTotalPrice());
|
||||
}
|
||||
saleOutMapper.updateById(new ErpSaleOutDO().setId(id).setReceiptPrice(receiptPrice));
|
||||
}
|
||||
|
||||
private List<ErpSaleOutItemDO> validateSaleOutItems(List<ErpSaleOutSaveReqVO.Item> list) {
|
||||
// 1. 校验产品存在
|
||||
List<ErpProductDO> productList = productService.validProductList(
|
||||
@ -271,6 +284,15 @@ public class ErpSaleOutServiceImpl implements ErpSaleOutService {
|
||||
return saleOutMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErpSaleOutDO validateSaleOut(Long id) {
|
||||
ErpSaleOutDO saleOut = validateSaleOutExists(id);
|
||||
if (ObjectUtil.notEqual(saleOut.getStatus(), ErpAuditStatus.APPROVE.getStatus())) {
|
||||
throw exception(SALE_OUT_NOT_APPROVE);
|
||||
}
|
||||
return saleOut;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<ErpSaleOutDO> getSaleOutPage(ErpSaleOutPageReqVO pageReqVO) {
|
||||
return saleOutMapper.selectPage(pageReqVO);
|
||||
|
@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleReturnDO;
|
||||
import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleReturnItemDO;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@ -40,6 +41,14 @@ public interface ErpSaleReturnService {
|
||||
*/
|
||||
void updateSaleReturnStatus(Long id, Integer status);
|
||||
|
||||
/**
|
||||
* 更新销售退货的退款金额
|
||||
*
|
||||
* @param id 编号
|
||||
* @param refundPrice 退款金额
|
||||
*/
|
||||
void updateSaleReturnRefundPrice(Long id, BigDecimal refundPrice);
|
||||
|
||||
/**
|
||||
* 删除销售退货
|
||||
*
|
||||
@ -55,6 +64,14 @@ public interface ErpSaleReturnService {
|
||||
*/
|
||||
ErpSaleReturnDO getSaleReturn(Long id);
|
||||
|
||||
/**
|
||||
* 校验销售退货,已经审核通过
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 销售退货
|
||||
*/
|
||||
ErpSaleReturnDO validateSaleReturn(Long id);
|
||||
|
||||
/**
|
||||
* 获得销售退货分页
|
||||
*
|
||||
|
@ -148,10 +148,7 @@ public class ErpSaleReturnServiceImpl implements ErpSaleReturnService {
|
||||
saleReturn.setDiscountPercent(BigDecimal.ZERO);
|
||||
}
|
||||
saleReturn.setDiscountPrice(MoneyUtils.priceMultiplyPercent(saleReturn.getTotalPrice(), saleReturn.getDiscountPercent()));
|
||||
saleReturn.setTotalPrice(saleReturn.getTotalPrice().subtract(saleReturn.getDiscountPrice()));
|
||||
// 计算应退金额
|
||||
BigDecimal allPrice = saleReturn.getTotalPrice().add(saleReturn.getOtherPrice());
|
||||
saleReturn.setDebtPrice(allPrice.subtract(saleReturn.getRefundPrice()));
|
||||
saleReturn.setTotalPrice(saleReturn.getTotalPrice().subtract(saleReturn.getDiscountPrice().add(saleReturn.getOtherPrice())));
|
||||
}
|
||||
|
||||
private void updateSaleOrderReturnCount(Long orderId) {
|
||||
@ -174,6 +171,10 @@ public class ErpSaleReturnServiceImpl implements ErpSaleReturnService {
|
||||
if (saleReturn.getStatus().equals(status)) {
|
||||
throw exception(approve ? SALE_RETURN_APPROVE_FAIL : SALE_RETURN_PROCESS_FAIL);
|
||||
}
|
||||
// 1.3 校验已退款
|
||||
if (approve && saleReturn.getRefundPrice().compareTo(BigDecimal.ZERO) > 0) {
|
||||
throw exception(SALE_RETURN_PROCESS_FAIL_EXISTS_REFUND);
|
||||
}
|
||||
|
||||
// 2. 更新状态
|
||||
int updateCount = saleReturnMapper.updateByIdAndStatus(id, saleReturn.getStatus(),
|
||||
@ -194,6 +195,18 @@ public class ErpSaleReturnServiceImpl implements ErpSaleReturnService {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSaleReturnRefundPrice(Long id, BigDecimal refundPrice) {
|
||||
ErpSaleReturnDO saleReturn = saleReturnMapper.selectById(id);
|
||||
if (saleReturn.getRefundPrice().equals(refundPrice)) {
|
||||
return;
|
||||
}
|
||||
if (refundPrice.compareTo(saleReturn.getTotalPrice()) > 0) {
|
||||
throw exception(SALE_RETURN_FAIL_REFUND_PRICE_EXCEED, refundPrice, saleReturn.getTotalPrice());
|
||||
}
|
||||
saleReturnMapper.updateById(new ErpSaleReturnDO().setId(id).setRefundPrice(refundPrice));
|
||||
}
|
||||
|
||||
private List<ErpSaleReturnItemDO> validateSaleReturnItems(List<ErpSaleReturnSaveReqVO.Item> list) {
|
||||
// 1. 校验产品存在
|
||||
List<ErpProductDO> productList = productService.validProductList(
|
||||
@ -271,6 +284,15 @@ public class ErpSaleReturnServiceImpl implements ErpSaleReturnService {
|
||||
return saleReturnMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErpSaleReturnDO validateSaleReturn(Long id) {
|
||||
ErpSaleReturnDO saleReturn = validateSaleReturnExists(id);
|
||||
if (ObjectUtil.notEqual(saleReturn.getStatus(), ErpAuditStatus.APPROVE.getStatus())) {
|
||||
throw exception(SALE_RETURN_NOT_APPROVE);
|
||||
}
|
||||
return saleReturn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<ErpSaleReturnDO> getSaleReturnPage(ErpSaleReturnPageReqVO pageReqVO) {
|
||||
return saleReturnMapper.selectPage(pageReqVO);
|
||||
|
Loading…
Reference in New Issue
Block a user