完善首付款管理模块
This commit is contained in:
+56
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments from this software for such purposes. Copyright of this software remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.system.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.mp.base.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 开票项目实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("blade_invoice_item")
|
||||
@Schema(description = "开票项目")
|
||||
public class InvoiceItem extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "货物或服务简称")
|
||||
private String shortName;
|
||||
|
||||
@Schema(description = "税收分类编码")
|
||||
private String taxClassificationCode;
|
||||
|
||||
@Schema(description = "商品和服务分类名称")
|
||||
private String categoryName;
|
||||
|
||||
@Schema(description = "默认税率")
|
||||
private BigDecimal defaultTaxRate;
|
||||
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments from this software for such purposes. Copyright of this software remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.system.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.system.pojo.entity.InvoiceItem;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 开票项目视图实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Schema(description = "开票项目")
|
||||
public class InvoiceItemVO extends InvoiceItem {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableField(exist = false)
|
||||
@Schema(description = "创建部门名称")
|
||||
private String createDeptName;
|
||||
|
||||
@TableField(exist = false)
|
||||
@Schema(description = "更新人姓名")
|
||||
private String updateUserName;
|
||||
|
||||
}
|
||||
+14
@@ -30,6 +30,7 @@ import lombok.Data;
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -42,6 +43,19 @@ public class InvoiceReceiptSaveRequest implements Serializable {
|
||||
@Serial private static final long serialVersionUID = 1L;
|
||||
private Long id;
|
||||
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;
|
||||
private String bankName;
|
||||
private String bankAccount;
|
||||
private String issuingBank;
|
||||
private String kingdeeBillNo;
|
||||
private String kingdeeStatus;
|
||||
private String phone;
|
||||
private String customerEmails;
|
||||
private String departmentEmails;
|
||||
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments from this software for such purposes. Copyright of this software remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.system.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.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
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.tenant.annotation.NonDS;
|
||||
import org.springblade.core.tool.api.R;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.system.pojo.entity.InvoiceItem;
|
||||
import org.springblade.system.pojo.vo.InvoiceItemVO;
|
||||
import org.springblade.system.service.IInvoiceItemService;
|
||||
import org.springblade.system.wrapper.InvoiceItemWrapper;
|
||||
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
|
||||
*/
|
||||
@NonDS
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
@PreAuth(menu = "invoice_item")
|
||||
@RequestMapping("/invoice-item")
|
||||
@Tag(name = "开票项目", description = "开票项目")
|
||||
public class InvoiceItemController extends BladeController {
|
||||
|
||||
private final IInvoiceItemService invoiceItemService;
|
||||
|
||||
@GetMapping("/detail")
|
||||
@ApiOperationSupport(order = 1)
|
||||
@Operation(summary = "详情", description = "传入invoiceItem")
|
||||
public R<InvoiceItemVO> detail(InvoiceItem invoiceItem) {
|
||||
InvoiceItem detail = invoiceItemService.getOne(Condition.getQueryWrapper(invoiceItem));
|
||||
return R.data(InvoiceItemWrapper.build().entityVO(detail));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperationSupport(order = 2)
|
||||
@Operation(summary = "分页", description = "传入invoiceItem")
|
||||
public R<IPage<InvoiceItemVO>> list(InvoiceItemVO invoiceItem, Query query) {
|
||||
return R.data(invoiceItemService.selectInvoiceItemPage(Condition.getPage(query), invoiceItem));
|
||||
}
|
||||
|
||||
@PostMapping("/submit")
|
||||
@ApiOperationSupport(order = 3)
|
||||
@Operation(summary = "新增或修改", description = "传入invoiceItem")
|
||||
public R submit(@Valid @RequestBody InvoiceItem invoiceItem) {
|
||||
return R.status(invoiceItemService.submit(invoiceItem));
|
||||
}
|
||||
|
||||
@PostMapping("/remove")
|
||||
@ApiOperationSupport(order = 4)
|
||||
@Operation(summary = "逻辑删除", description = "传入ids")
|
||||
public R remove(@Parameter(description = "主键集合", required = true) @RequestParam String ids) {
|
||||
return R.status(invoiceItemService.deleteLogic(Func.toLongList(ids)));
|
||||
}
|
||||
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments from this software for such purposes. Copyright of this software remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.system.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springblade.system.pojo.entity.InvoiceItem;
|
||||
import org.springblade.system.pojo.vo.InvoiceItemVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 开票项目 Mapper 接口
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface InvoiceItemMapper extends BaseMapper<InvoiceItem> {
|
||||
|
||||
List<InvoiceItemVO> selectInvoiceItemPage(IPage<InvoiceItemVO> page,
|
||||
@Param("invoiceItem") InvoiceItemVO invoiceItem);
|
||||
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.springblade.system.mapper.InvoiceItemMapper">
|
||||
<resultMap id="invoiceItemResultMap" type="org.springblade.system.pojo.vo.InvoiceItemVO">
|
||||
<result column="id" property="id"/>
|
||||
<result column="create_user" property="createUser"/>
|
||||
<result column="create_dept" property="createDept"/>
|
||||
<result column="create_time" property="createTime"/>
|
||||
<result column="update_user" property="updateUser"/>
|
||||
<result column="update_time" property="updateTime"/>
|
||||
<result column="status" property="status"/>
|
||||
<result column="is_deleted" property="isDeleted"/>
|
||||
<result column="create_dept_name" property="createDeptName"/>
|
||||
<result column="update_user_name" property="updateUserName"/>
|
||||
<result column="short_name" property="shortName"/>
|
||||
<result column="tax_classification_code" property="taxClassificationCode"/>
|
||||
<result column="category_name" property="categoryName"/>
|
||||
<result column="default_tax_rate" property="defaultTaxRate"/>
|
||||
</resultMap>
|
||||
<select id="selectInvoiceItemPage" resultMap="invoiceItemResultMap">
|
||||
SELECT bii.*, bd.dept_name AS create_dept_name, bu.real_name AS update_user_name
|
||||
FROM blade_invoice_item bii
|
||||
LEFT JOIN blade_dept bd ON bd.id = bii.create_dept
|
||||
LEFT JOIN blade_user bu ON bu.id = bii.update_user
|
||||
WHERE bii.is_deleted = 0
|
||||
<if test="invoiceItem.shortName != null and invoiceItem.shortName != ''">
|
||||
<bind name="shortNameLike" value="'%' + invoiceItem.shortName + '%'"/>
|
||||
AND bii.short_name LIKE #{shortNameLike}
|
||||
</if>
|
||||
<if test="invoiceItem.categoryName != null and invoiceItem.categoryName != ''">
|
||||
<bind name="categoryNameLike" value="'%' + invoiceItem.categoryName + '%'"/>
|
||||
AND bii.category_name LIKE #{categoryNameLike}
|
||||
</if>
|
||||
<if test="invoiceItem.taxClassificationCode != null and invoiceItem.taxClassificationCode != ''">
|
||||
<bind name="taxCodeLike" value="'%' + invoiceItem.taxClassificationCode + '%'"/>
|
||||
AND bii.tax_classification_code LIKE #{taxCodeLike}
|
||||
</if>
|
||||
ORDER BY bii.create_time DESC
|
||||
</select>
|
||||
</mapper>
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments from this software for such purposes. Copyright of this software remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.system.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.springblade.core.mp.base.BaseService;
|
||||
import org.springblade.system.pojo.entity.InvoiceItem;
|
||||
import org.springblade.system.pojo.vo.InvoiceItemVO;
|
||||
|
||||
/**
|
||||
* 开票项目服务类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface IInvoiceItemService extends BaseService<InvoiceItem> {
|
||||
|
||||
IPage<InvoiceItemVO> selectInvoiceItemPage(IPage<InvoiceItemVO> page, InvoiceItemVO invoiceItem);
|
||||
|
||||
boolean submit(InvoiceItem invoiceItem);
|
||||
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments from this software for such purposes. Copyright of this software remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.system.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import org.springblade.core.log.exception.ServiceException;
|
||||
import org.springblade.core.mp.base.BaseServiceImpl;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.system.mapper.InvoiceItemMapper;
|
||||
import org.springblade.system.pojo.entity.InvoiceItem;
|
||||
import org.springblade.system.pojo.vo.InvoiceItemVO;
|
||||
import org.springblade.system.service.IInvoiceItemService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 开票项目服务实现类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Service
|
||||
public class InvoiceItemServiceImpl extends BaseServiceImpl<InvoiceItemMapper, InvoiceItem>
|
||||
implements IInvoiceItemService {
|
||||
|
||||
private static final int SHORT_NAME_MAX_LENGTH = 100;
|
||||
private static final int TAX_CODE_MAX_LENGTH = 30;
|
||||
private static final int CATEGORY_NAME_MAX_LENGTH = 200;
|
||||
|
||||
@Override
|
||||
public IPage<InvoiceItemVO> selectInvoiceItemPage(IPage<InvoiceItemVO> page, InvoiceItemVO invoiceItem) {
|
||||
return page.setRecords(baseMapper.selectInvoiceItemPage(page, invoiceItem));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean submit(InvoiceItem invoiceItem) {
|
||||
prepare(invoiceItem);
|
||||
validate(invoiceItem);
|
||||
return saveOrUpdate(invoiceItem);
|
||||
}
|
||||
|
||||
private void prepare(InvoiceItem invoiceItem) {
|
||||
invoiceItem.setShortName(trim(invoiceItem.getShortName()));
|
||||
invoiceItem.setTaxClassificationCode(trim(invoiceItem.getTaxClassificationCode()));
|
||||
invoiceItem.setCategoryName(trim(invoiceItem.getCategoryName()));
|
||||
if (Func.isEmpty(invoiceItem.getStatus())) {
|
||||
invoiceItem.setStatus(1);
|
||||
}
|
||||
}
|
||||
|
||||
private void validate(InvoiceItem invoiceItem) {
|
||||
if (Func.isEmpty(invoiceItem.getShortName())) throw new ServiceException("货物或服务简称不能为空");
|
||||
if (invoiceItem.getShortName().length() > SHORT_NAME_MAX_LENGTH) throw new ServiceException("货物或服务简称不能超过100字");
|
||||
if (Func.isEmpty(invoiceItem.getTaxClassificationCode())) throw new ServiceException("税收分类编码不能为空");
|
||||
if (invoiceItem.getTaxClassificationCode().length() > TAX_CODE_MAX_LENGTH) throw new ServiceException("税收分类编码不能超过30字");
|
||||
if (Func.isEmpty(invoiceItem.getCategoryName())) throw new ServiceException("商品和服务分类名称不能为空");
|
||||
if (invoiceItem.getCategoryName().length() > CATEGORY_NAME_MAX_LENGTH) throw new ServiceException("商品和服务分类名称不能超过200字");
|
||||
BigDecimal taxRate = invoiceItem.getDefaultTaxRate();
|
||||
if (taxRate == null) throw new ServiceException("默认税率不能为空");
|
||||
if (taxRate.compareTo(BigDecimal.ZERO) < 0 || taxRate.compareTo(new BigDecimal("100")) > 0) throw new ServiceException("默认税率必须在0到100之间");
|
||||
boolean duplicate = count(Wrappers.<InvoiceItem>lambdaQuery()
|
||||
.eq(InvoiceItem::getTaxClassificationCode, invoiceItem.getTaxClassificationCode())
|
||||
.eq(InvoiceItem::getShortName, invoiceItem.getShortName())
|
||||
.eq(InvoiceItem::getIsDeleted, 0)
|
||||
.ne(Func.isNotEmpty(invoiceItem.getId()), InvoiceItem::getId, invoiceItem.getId())) > 0;
|
||||
if (duplicate) throw new ServiceException("该开票项目已存在");
|
||||
}
|
||||
|
||||
private String trim(String value) {
|
||||
return value == null ? "" : value.trim();
|
||||
}
|
||||
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments from this software for such purposes. Copyright of this software remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.system.wrapper;
|
||||
|
||||
import org.springblade.core.mp.support.BaseEntityWrapper;
|
||||
import org.springblade.core.tool.utils.BeanUtil;
|
||||
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.InvoiceItem;
|
||||
import org.springblade.system.pojo.vo.InvoiceItemVO;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 开票项目包装类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public class InvoiceItemWrapper extends BaseEntityWrapper<InvoiceItem, InvoiceItemVO> {
|
||||
|
||||
public static InvoiceItemWrapper build() {
|
||||
return new InvoiceItemWrapper();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvoiceItemVO entityVO(InvoiceItem invoiceItem) {
|
||||
InvoiceItemVO vo = Objects.requireNonNull(BeanUtil.copyProperties(invoiceItem, InvoiceItemVO.class));
|
||||
vo.setCreateDeptName(Func.isEmpty(invoiceItem.getCreateDept()) ? "" : SysCache.getDeptName(invoiceItem.getCreateDept()));
|
||||
vo.setUpdateUserName(UserCache.getUserRealName(invoiceItem.getUpdateUser()));
|
||||
return vo;
|
||||
}
|
||||
|
||||
}
|
||||
+69
-23
@@ -70,9 +70,11 @@ import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
@@ -183,14 +185,16 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl<InvoiceApplic
|
||||
List<FormalSettlement> settlements = distinctIds(settlementIds).stream().map(this::availableSettlement).toList();
|
||||
assertCompatible(settlements);
|
||||
FormalSettlement first = settlements.get(0);
|
||||
CustomerArchive customer = findCustomer(first.getPayerName());
|
||||
CustomerArchive customer = findCustomer(first.getPayeeName());
|
||||
List<CustomerInvoiceInfo> invoiceInfos = customer == null ? List.of() : activeInvoiceInfos(customer.getId());
|
||||
Map<String, Object> 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.<CustomerInvoiceInfo>lambdaQuery().eq(CustomerInvoiceInfo::getCustomerId, customer.getId())
|
||||
.eq(CustomerInvoiceInfo::getStatus, 1).orderByDesc(CustomerInvoiceInfo::getIsDefault)));
|
||||
// 应付结算单的开票方(payeeName)是客商,受票方信息和部门邮箱均来源于该客商发票信息。
|
||||
result.put("invoices", invoiceInfos);
|
||||
result.put("invoiceInfos", invoiceInfos);
|
||||
result.put("departmentEmails", invoiceInfoEmails(invoiceInfos));
|
||||
result.put("contacts", customer == null ? List.of() : customerContactMapper.selectList(
|
||||
Wrappers.<CustomerContact>lambdaQuery().eq(CustomerContact::getCustomerId, customer.getId())
|
||||
.eq(CustomerContact::getStatus, 1).orderByDesc(CustomerContact::getIsDefault)));
|
||||
@@ -217,7 +221,6 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl<InvoiceApplic
|
||||
Map<Long, FormalSettlement> 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());
|
||||
@@ -226,21 +229,18 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl<InvoiceApplic
|
||||
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("请选择受票方有效的开票信息");
|
||||
}
|
||||
CustomerArchive customer = findCustomer(first.getPayeeName());
|
||||
if (customer == null) throw new ServiceException("未找到正式结算单开票方对应的客商档案");
|
||||
List<CustomerInvoiceInfo> invoiceInfos = activeInvoiceInfos(customer.getId());
|
||||
CustomerInvoiceInfo invoiceInfo = invoiceInfos.stream()
|
||||
.filter(item -> Objects.equals(item.getId(), request.getReceiverInvoiceInfoId()))
|
||||
.findFirst().orElseThrow(() -> new ServiceException("请选择受票方有效的开票信息"));
|
||||
String departmentEmails = normalizeDepartmentEmails(request.getDepartmentEmails(), invoiceInfos);
|
||||
String invoiceTitle = required(invoiceInfo.getInvoiceTitle(), "受票方单位");
|
||||
String taxpayerNo = limit(invoiceInfo.getTaxNo(), 20, "纳税人识别号");
|
||||
String bankName = limit(invoiceInfo.getBankName(), 100, "开户行");
|
||||
@@ -271,7 +271,7 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl<InvoiceApplic
|
||||
entity.setInvoiceAmount(lineTotal);
|
||||
entity.setUndertakingDeptId(first.getDeptId());
|
||||
entity.setUndertakingDeptName(first.getDeptName());
|
||||
entity.setDepartmentEmails(normalizeEmails(request.getDepartmentEmails()));
|
||||
entity.setDepartmentEmails(departmentEmails);
|
||||
entity.setReceiverInvoiceInfoId(invoiceInfo.getId());
|
||||
entity.setTaxpayerNo(taxpayerNo);
|
||||
entity.setBankName(bankName);
|
||||
@@ -535,10 +535,40 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl<InvoiceApplic
|
||||
|
||||
private CustomerArchive findCustomer(String name) {
|
||||
if (Func.isEmpty(name)) return null;
|
||||
return customerArchiveMapper.selectOne(Wrappers.<CustomerArchive>lambdaQuery()
|
||||
.and(wrapper -> wrapper.eq(CustomerArchive::getFullName, name).or().eq(CustomerArchive::getShortName, name))
|
||||
String value = name.trim();
|
||||
CustomerArchive customer = customerArchiveMapper.selectOne(Wrappers.<CustomerArchive>lambdaQuery()
|
||||
.and(wrapper -> wrapper.eq(CustomerArchive::getFullName, value).or().eq(CustomerArchive::getShortName, value))
|
||||
.eq(CustomerArchive::getStatus, 1)
|
||||
.eq(CustomerArchive::getIsDeleted, 0).last("limit 1"));
|
||||
if (customer != null) return customer;
|
||||
String normalized = normalizeCustomerName(value);
|
||||
return customerArchiveMapper.selectList(Wrappers.<CustomerArchive>lambdaQuery()
|
||||
.eq(CustomerArchive::getStatus, 1)
|
||||
.eq(CustomerArchive::getIsDeleted, 0))
|
||||
.stream()
|
||||
.filter(item -> normalized.equals(normalizeCustomerName(item.getFullName()))
|
||||
|| normalized.equals(normalizeCustomerName(item.getShortName())))
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
private String normalizeCustomerName(String value) {
|
||||
return value == null ? "" : value.replaceAll("\\s+", "");
|
||||
}
|
||||
|
||||
private List<CustomerInvoiceInfo> activeInvoiceInfos(Long customerId) {
|
||||
return customerInvoiceInfoMapper.selectList(Wrappers.<CustomerInvoiceInfo>lambdaQuery()
|
||||
.eq(CustomerInvoiceInfo::getCustomerId, customerId)
|
||||
.eq(CustomerInvoiceInfo::getStatus, 1)
|
||||
.eq(CustomerInvoiceInfo::getIsDeleted, 0)
|
||||
.orderByDesc(CustomerInvoiceInfo::getIsDefault)
|
||||
.orderByAsc(CustomerInvoiceInfo::getCreateTime));
|
||||
}
|
||||
|
||||
private List<String> invoiceInfoEmails(List<CustomerInvoiceInfo> invoiceInfos) {
|
||||
return invoiceInfos.stream().map(CustomerInvoiceInfo::getEmail).filter(Func::isNotEmpty)
|
||||
.flatMap(value -> splitEmails(value).stream())
|
||||
.collect(Collectors.toMap(email -> email.toLowerCase(Locale.ROOT), Function.identity(),
|
||||
(first, duplicate) -> first, LinkedHashMap::new)).values().stream().toList();
|
||||
}
|
||||
|
||||
private void changeStatus(Long id, String from, String to, String actionType, String node, String reason) {
|
||||
@@ -587,12 +617,28 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl<InvoiceApplic
|
||||
.likeRight(InvoiceApplication::getApplicationNo, prefix)) + 1);
|
||||
}
|
||||
|
||||
private String normalizeEmails(String value) {
|
||||
List<String> emails = value == null ? List.of() : List.of(value.split("[;,,;]"));
|
||||
List<String> normalized = emails.stream().map(String::trim).filter(item -> !item.isEmpty()).distinct().toList();
|
||||
private String normalizeDepartmentEmails(String value, List<CustomerInvoiceInfo> invoiceInfos) {
|
||||
Map<String, String> configuredEmails = invoiceInfoEmails(invoiceInfos).stream()
|
||||
.collect(Collectors.toMap(email -> email.toLowerCase(Locale.ROOT), Function.identity(),
|
||||
(first, duplicate) -> first, LinkedHashMap::new));
|
||||
if (configuredEmails.isEmpty()) throw new ServiceException("当前客商的开票信息未配置邮箱");
|
||||
List<String> normalized = splitEmails(value).stream()
|
||||
.collect(Collectors.toMap(email -> email.toLowerCase(Locale.ROOT), Function.identity(),
|
||||
(first, duplicate) -> first, LinkedHashMap::new)).values().stream().toList();
|
||||
if (normalized.isEmpty() || normalized.size() > 3) throw new ServiceException("部门邮箱必填且最多选择3个");
|
||||
normalized.forEach(email -> validateEmail(email, "部门邮箱"));
|
||||
return String.join(";", normalized);
|
||||
List<String> selectedEmails = normalized.stream().map(email -> {
|
||||
validateEmail(email, "部门邮箱");
|
||||
String configuredEmail = configuredEmails.get(email.toLowerCase(Locale.ROOT));
|
||||
if (configuredEmail == null) throw new ServiceException("部门邮箱必须选择当前客商开票信息中配置的邮箱");
|
||||
return configuredEmail;
|
||||
}).distinct().toList();
|
||||
return String.join(";", selectedEmails);
|
||||
}
|
||||
|
||||
private List<String> splitEmails(String value) {
|
||||
if (Func.isEmpty(value)) return List.of();
|
||||
return Arrays.stream(value.split("[;,,;]"))
|
||||
.map(String::trim).filter(item -> !item.isEmpty()).toList();
|
||||
}
|
||||
|
||||
private String validateEmail(String value, String name) {
|
||||
|
||||
+39
-29
@@ -212,6 +212,7 @@ public class InvoiceReceiptServiceImpl extends BaseServiceImpl<InvoiceReceiptMap
|
||||
InvoiceReceipt entity = creating ? new InvoiceReceipt() : editable(request.getId());
|
||||
List<Long> oldSettlementIds = entity.getId() == null ? List.of() : relationSettlementIds(entity.getId());
|
||||
KingdeeInvoicePool invoice = lockedInvoice(request.getKingdeeInvoicePoolId());
|
||||
if (invoice == null) invoice = invoiceSnapshot(request);
|
||||
assertInvoiceUnused(invoice, entity.getId());
|
||||
|
||||
Map<Long, InvoiceReceiptSaveRequest.SettlementRow> requestedRows = distinctSettlementRows(
|
||||
@@ -219,10 +220,7 @@ public class InvoiceReceiptServiceImpl extends BaseServiceImpl<InvoiceReceiptMap
|
||||
Map<Long, FormalSettlement> settlementMap = lockSettlements(requestedRows.keySet().stream().sorted().toList());
|
||||
List<FormalSettlement> 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<Long, InvoiceReceiptSaveRequest.SettlementRow> entry : requestedRows.entrySet()) {
|
||||
FormalSettlement settlement = settlementMap.get(entry.getKey());
|
||||
BigDecimal allocated = nonNegative(entry.getValue().getAllocatedInvoiceAmount(), "分摊发票金额");
|
||||
@@ -231,10 +229,6 @@ public class InvoiceReceiptServiceImpl extends BaseServiceImpl<InvoiceReceiptMap
|
||||
throw new ServiceException("结算单" + settlement.getFormalSettlementNo()
|
||||
+ "的累计收票金额不能超过结算总应付含税金额");
|
||||
}
|
||||
allocatedTotal = allocatedTotal.add(allocated);
|
||||
}
|
||||
if (allocatedTotal.compareTo(invoiceAmount) != 0) {
|
||||
throw new ServiceException("分摊发票金额总和必须等于发票开票金额");
|
||||
}
|
||||
|
||||
if (creating) {
|
||||
@@ -422,14 +416,46 @@ public class InvoiceReceiptServiceImpl extends BaseServiceImpl<InvoiceReceiptMap
|
||||
}
|
||||
|
||||
private KingdeeInvoicePool lockedInvoice(Long id) {
|
||||
KingdeeInvoicePool invoice = invoicePoolMapper.selectOne(Wrappers.<KingdeeInvoicePool>lambdaQuery()
|
||||
return invoicePoolMapper.selectOne(Wrappers.<KingdeeInvoicePool>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(), "发票号码");
|
||||
|
||||
private KingdeeInvoicePool invoiceSnapshot(InvoiceReceiptSaveRequest request) {
|
||||
KingdeeInvoicePool invoice = new KingdeeInvoicePool();
|
||||
invoice.setId(request.getKingdeeInvoicePoolId());
|
||||
invoice.setInvoiceNo(request.getInvoiceNo());
|
||||
invoice.setInvoiceDate(request.getInvoiceDate());
|
||||
invoice.setInvoiceType(request.getInvoiceType());
|
||||
invoice.setTaxRate(request.getTaxRate());
|
||||
invoice.setInvoiceAmount(request.getInvoiceAmount());
|
||||
invoice.setTaxAmount(request.getTaxAmount());
|
||||
invoice.setReceiverName(request.getReceiverName());
|
||||
invoice.setIssuerName(request.getIssuerName());
|
||||
invoice.setBankName(request.getBankName());
|
||||
invoice.setBankAccount(request.getBankAccount());
|
||||
invoice.setIssuingBank(request.getIssuingBank());
|
||||
invoice.setKingdeeBillNo(request.getKingdeeBillNo());
|
||||
invoice.setKingdeeStatus(request.getKingdeeStatus());
|
||||
return invoice;
|
||||
}
|
||||
|
||||
private KingdeeInvoicePool invoiceSnapshot(InvoiceReceipt receipt) {
|
||||
KingdeeInvoicePool invoice = new KingdeeInvoicePool();
|
||||
invoice.setId(receipt.getKingdeeInvoicePoolId());
|
||||
invoice.setInvoiceNo(receipt.getInvoiceNo());
|
||||
invoice.setInvoiceDate(receipt.getInvoiceDate());
|
||||
invoice.setInvoiceType(receipt.getInvoiceType());
|
||||
invoice.setTaxRate(receipt.getTaxRate());
|
||||
invoice.setInvoiceAmount(receipt.getInvoiceAmount());
|
||||
invoice.setTaxAmount(receipt.getTaxAmount());
|
||||
invoice.setReceiverName(receipt.getReceiverName());
|
||||
invoice.setIssuerName(receipt.getIssuerName());
|
||||
invoice.setBankName(receipt.getBankName());
|
||||
invoice.setBankAccount(receipt.getBankAccount());
|
||||
invoice.setIssuingBank(receipt.getIssuingBank());
|
||||
invoice.setKingdeeBillNo(receipt.getKingdeeBillNo());
|
||||
invoice.setKingdeeStatus(receipt.getKingdeeStatus());
|
||||
return invoice;
|
||||
}
|
||||
|
||||
@@ -456,17 +482,6 @@ public class InvoiceReceiptServiceImpl extends BaseServiceImpl<InvoiceReceiptMap
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -528,6 +543,7 @@ public class InvoiceReceiptServiceImpl extends BaseServiceImpl<InvoiceReceiptMap
|
||||
|
||||
private void validateStoredAllocation(InvoiceReceipt entity) {
|
||||
KingdeeInvoicePool invoice = lockedInvoice(entity.getKingdeeInvoicePoolId());
|
||||
if (invoice == null) invoice = invoiceSnapshot(entity);
|
||||
assertInvoiceUnused(invoice, entity.getId());
|
||||
List<InvoiceReceiptSettlement> relations = settlementRelationMapper.selectList(
|
||||
Wrappers.<InvoiceReceiptSettlement>lambdaQuery()
|
||||
@@ -545,8 +561,6 @@ public class InvoiceReceiptServiceImpl extends BaseServiceImpl<InvoiceReceiptMap
|
||||
.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(), "分摊发票金额");
|
||||
@@ -555,10 +569,6 @@ public class InvoiceReceiptServiceImpl extends BaseServiceImpl<InvoiceReceiptMap
|
||||
throw new ServiceException("结算单" + settlement.getFormalSettlementNo()
|
||||
+ "的累计收票金额不能超过结算总应付含税金额");
|
||||
}
|
||||
allocatedTotal = allocatedTotal.add(allocated);
|
||||
}
|
||||
if (allocatedTotal.compareTo(positive(invoice.getInvoiceAmount(), "开票金额")) != 0) {
|
||||
throw new ServiceException("分摊发票金额总和必须等于发票开票金额");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-15
@@ -126,7 +126,7 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl<KingdeeReceiptFlowMa
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> settlementCandidates(String keyword, Long flowId) {
|
||||
KingdeeReceiptFlow flow = existing(flowId);
|
||||
existing(flowId);
|
||||
List<FormalSettlement> settlements = formalSettlementMapper.selectList(
|
||||
Wrappers.<FormalSettlement>lambdaQuery()
|
||||
.eq(FormalSettlement::getSettlementType, RECEIVABLE)
|
||||
@@ -139,9 +139,7 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl<KingdeeReceiptFlowMa
|
||||
.orderByDesc(FormalSettlement::getCreateTime)
|
||||
.last("limit 200"));
|
||||
return settlements.stream()
|
||||
.filter(settlement -> Func.isEmpty(flow.getCounterpartyName())
|
||||
|| sameName(flow.getCounterpartyName(), settlement.getPayerName()))
|
||||
.map(settlement -> candidateRow(settlement))
|
||||
.map(this::candidateRow)
|
||||
.filter(row -> ((BigDecimal) row.get("remainingReceiptAmount")).compareTo(BigDecimal.ZERO) > 0)
|
||||
.toList();
|
||||
}
|
||||
@@ -163,7 +161,6 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl<KingdeeReceiptFlowMa
|
||||
Map<Long, FormalSettlement> settlementMap = lockSettlements(settlementIds);
|
||||
List<FormalSettlement> settlements = settlementIds.stream().map(settlementMap::get).toList();
|
||||
assertCompatible(settlements);
|
||||
assertCounterparty(flow, settlements.get(0));
|
||||
|
||||
Map<Long, BigDecimal> previousClaimedMap = new LinkedHashMap<>();
|
||||
BigDecimal allocatedTotal = BigDecimal.ZERO;
|
||||
@@ -351,16 +348,6 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl<KingdeeReceiptFlowMa
|
||||
}
|
||||
}
|
||||
|
||||
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.<ReceiptClaimSettlement>lambdaQuery()
|
||||
.eq(ReceiptClaimSettlement::getFormalSettlementId, settlementId)
|
||||
|
||||
@@ -24,7 +24,7 @@ CREATE TABLE IF NOT EXISTS `blade_invoice_application` (
|
||||
`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,
|
||||
`department_emails` varchar(320) DEFAULT NULL COMMENT '部门邮箱(多个以分号分隔,最多3个)',
|
||||
`receiver_invoice_info_id` bigint(20) DEFAULT NULL,
|
||||
`taxpayer_no` varchar(20) DEFAULT NULL,
|
||||
`bank_name` varchar(100) DEFAULT NULL,
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
-- 开票申请部门邮箱支持最多3个客商开票信息邮箱,以分号分隔保存。
|
||||
ALTER TABLE `blade_invoice_application`
|
||||
MODIFY COLUMN `department_emails` varchar(320) DEFAULT NULL COMMENT '部门邮箱(多个以分号分隔,最多3个)';
|
||||
@@ -0,0 +1,28 @@
|
||||
-- 开票项目
|
||||
DROP TABLE IF EXISTS `blade_invoice_item`;
|
||||
CREATE TABLE `blade_invoice_item` (
|
||||
`id` bigint NOT NULL COMMENT '主键',
|
||||
`short_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '货物或服务简称',
|
||||
`tax_classification_code` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '税收分类编码',
|
||||
`category_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '商品和服务分类名称',
|
||||
`default_tax_rate` decimal(6,2) NOT NULL DEFAULT '0.00' COMMENT '默认税率(百分比)',
|
||||
`create_user` bigint DEFAULT NULL COMMENT '创建人',
|
||||
`create_dept` bigint DEFAULT NULL COMMENT '创建部门',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_user` bigint DEFAULT NULL COMMENT '修改人',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '修改时间',
|
||||
`status` int DEFAULT 1 COMMENT '状态',
|
||||
`is_deleted` int DEFAULT 0 COMMENT '是否已删除',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_invoice_item_code_name` (`tax_classification_code`,`short_name`),
|
||||
KEY `idx_invoice_item_category` (`category_name`),
|
||||
KEY `idx_invoice_item_short_name` (`short_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='开票项目';
|
||||
|
||||
-- 系统管理(parent_id=1164733399668962201)
|
||||
INSERT INTO `blade_menu` (`id`,`parent_id`,`code`,`name`,`alias`,`path`,`source`,`sort`,`category`,`action`,`is_open`,`component`,`remark`,`is_deleted`) VALUES
|
||||
(2075449200000000101,1123598815738675203,'invoice_item','开票项目','invoice_item','/base/invoice-item','iconfont icon-shoucang',61,1,0,1,NULL,'',0),
|
||||
(2075449200000000102,2075449200000000101,'invoice_item_add','新增','invoice_item_add','', '',1,2,1,1,NULL,'',0),
|
||||
(2075449200000000103,2075449200000000101,'invoice_item_edit','编辑','invoice_item_edit','', '',2,2,2,1,NULL,'',0),
|
||||
(2075449200000000104,2075449200000000101,'invoice_item_delete','删除','invoice_item_delete','', '',3,2,3,1,NULL,'',0),
|
||||
(2075449200000000105,2075449200000000101,'invoice_item_view','查看','invoice_item_view','', '',4,2,2,1,NULL,'',0);
|
||||
Reference in New Issue
Block a user