Browse Source

[feat]财务管理

修改国税发票的物料合计和数量合计的数据类型
国税发票新增 根据销售订单信息填充发票信息后端接口
国税发票新增 通过销售订单新增开票 后端接口
新增 国内开票公司前端页面

[fix] 销售管理
修改销售订单数据库的物料合计和数量合计的数据类型
修改销售订单前端页面:新增是否开票查询条件、新增列表展示是否开票字段;新增开票按钮;新增开票js方法,加上对条件限制:只允许选择一条销售订单、检查是否审核通过、检查是否允许开票
修改销售订单后端查询列表方法:新增是否开票字段
销售订单新增 加载开票弹窗后端接口:通过币种的不同转到不同的开票页面;新增 新增开票后端接口
dev
liuxiaoxu 1 month ago
parent
commit
2291a053f3
  1. 28
      ruoyi-admin/src/main/java/com/ruoyi/financial/domain/FinancialTaxInvoice.java
  2. 15
      ruoyi-admin/src/main/java/com/ruoyi/financial/service/IFinancialTaxInvoiceService.java
  3. 54
      ruoyi-admin/src/main/java/com/ruoyi/financial/service/impl/FinancialTaxInvoiceServiceImpl.java
  4. 36
      ruoyi-admin/src/main/java/com/ruoyi/system/controller/SysSalesOrderController.java
  5. 1
      ruoyi-admin/src/main/resources/mapper/system/SysSalesOrderMapper.xml
  6. 166
      ruoyi-admin/src/main/resources/templates/system/salesOrder/makeInvoiceRMB.html
  7. 52
      ruoyi-admin/src/main/resources/templates/system/salesOrder/salesOrder.html

28
ruoyi-admin/src/main/java/com/ruoyi/financial/domain/FinancialTaxInvoice.java

@ -98,11 +98,11 @@ public class FinancialTaxInvoice extends BaseEntity
/** 物料数合计 */
@Excel(name = "物料数合计")
private String materialSum;
private Long materialSum;
/** 数量合计 */
@Excel(name = "数量合计")
private String enterpriseSum;
private Long enterpriseSum;
/** 不含税总价(RMB) */
@Excel(name = "不含税总价(RMB)")
@ -377,25 +377,25 @@ public class FinancialTaxInvoice extends BaseEntity
{
return usdTax;
}
public void setMaterialSum(String materialSum)
{
this.materialSum = materialSum;
}
public String getMaterialSum()
{
public Long getMaterialSum() {
return materialSum;
}
public void setEnterpriseSum(String enterpriseSum)
{
this.enterpriseSum = enterpriseSum;
public void setMaterialSum(Long materialSum) {
this.materialSum = materialSum;
}
public String getEnterpriseSum()
{
public Long getEnterpriseSum() {
return enterpriseSum;
}
public void setNoRmbSum(BigDecimal noRmbSum)
public void setEnterpriseSum(Long enterpriseSum) {
this.enterpriseSum = enterpriseSum;
}
public void setNoRmbSum(BigDecimal noRmbSum)
{
this.noRmbSum = noRmbSum;
}

15
ruoyi-admin/src/main/java/com/ruoyi/financial/service/IFinancialTaxInvoiceService.java

@ -2,6 +2,7 @@ package com.ruoyi.financial.service;
import java.util.List;
import com.ruoyi.financial.domain.FinancialTaxInvoice;
import com.ruoyi.system.domain.SysSalesOrder;
/**
* 国税发票Service接口
@ -72,4 +73,18 @@ public interface IFinancialTaxInvoiceService
* @return
*/
int restoreFinancialTaxInvoiceById(Long taxInvoiceId);
/**
* 根据销售订单生成发票
* @param sysSalesOrder
* @return
*/
FinancialTaxInvoice fillInvoiceBySalesOrder(SysSalesOrder sysSalesOrder);
/**
* 销售订单新增开票
* @param financialTaxInvoice
* @return
*/
int makeInvoiceSave(FinancialTaxInvoice financialTaxInvoice);
}

54
ruoyi-admin/src/main/java/com/ruoyi/financial/service/impl/FinancialTaxInvoiceServiceImpl.java

@ -1,8 +1,13 @@
package com.ruoyi.financial.service.impl;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.system.domain.SysSalesOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.financial.mapper.FinancialTaxInvoiceMapper;
@ -22,6 +27,9 @@ public class FinancialTaxInvoiceServiceImpl implements IFinancialTaxInvoiceServi
@Autowired
private FinancialTaxInvoiceMapper financialTaxInvoiceMapper;
@Autowired
private RedisCache redisCache;
/**
* 查询国税发票
*
@ -123,4 +131,50 @@ public class FinancialTaxInvoiceServiceImpl implements IFinancialTaxInvoiceServi
{
return financialTaxInvoiceMapper.restoreFinancialTaxInvoiceById(taxInvoiceId);
}
/**
* 根据销售订单信息填充发票信息
*
* @param sysSalesOrder 销售订单信息
* @return 结果
*/
@Override
public FinancialTaxInvoice fillInvoiceBySalesOrder(SysSalesOrder sysSalesOrder) {
FinancialTaxInvoice financialTaxInvoice = new FinancialTaxInvoice();
financialTaxInvoice.setSalesOrderCode(sysSalesOrder.getSalesOrderCode());
financialTaxInvoice.setSalesOrderType(sysSalesOrder.getSalesOrderType());
financialTaxInvoice.setCommonCurrency(sysSalesOrder.getCommonCurrency());
financialTaxInvoice.setEnterpriseCode(sysSalesOrder.getEnterpriseCode());
financialTaxInvoice.setEnterpriseName(sysSalesOrder.getEnterpriseName());
financialTaxInvoice.setEnterpriseAddress(sysSalesOrder.getDeliveryAddress());
financialTaxInvoice.setContactNumber(sysSalesOrder.getContactNumber());
financialTaxInvoice.setEnterpriseSum(sysSalesOrder.getEnterpriseSum());
financialTaxInvoice.setMaterialSum(sysSalesOrder.getMaterialSum());
financialTaxInvoice.setRmbTaxSum(BigDecimal.valueOf(sysSalesOrder.getRmbTaxSum()));
financialTaxInvoice.setNoRmbSum(BigDecimal.valueOf(sysSalesOrder.getNoRmbSum()));
financialTaxInvoice.setUsdTaxSum(BigDecimal.valueOf(sysSalesOrder.getUsdTaxSum()));
financialTaxInvoice.setNoUsdSum(BigDecimal.valueOf(sysSalesOrder.getNoUsdSum()));
return financialTaxInvoice;
}
/**
* 销售订单新增开票信息
*
* @param financialTaxInvoice 发票信息
* @return 结果
*/
@Override
public int makeInvoiceSave(FinancialTaxInvoice financialTaxInvoice) {
String loginName = ShiroUtils.getLoginName();
financialTaxInvoice.setCreateBy(loginName);
financialTaxInvoice.setCreateTime(new Date());
String taxInvoiceCode = redisCache.generateBillNo("FP");
financialTaxInvoice.setTaxInvoiceCode(taxInvoiceCode);
financialTaxInvoice.setTaxInvoiceStatus("0");//待审核
financialTaxInvoice.setApplyUser(loginName);
financialTaxInvoice.setBusinessMembers(loginName);
return financialTaxInvoiceMapper.insertFinancialTaxInvoice(financialTaxInvoice);
}
}

36
ruoyi-admin/src/main/java/com/ruoyi/system/controller/SysSalesOrderController.java

@ -21,7 +21,9 @@ import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.erp.domain.ErpMaterialVo;
import com.ruoyi.financial.domain.FinancialTaxInvoice;
import com.ruoyi.financial.service.IFinancialReceivablesService;
import com.ruoyi.financial.service.IFinancialTaxInvoiceService;
import com.ruoyi.process.general.service.IProcessService;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.exportDto.SysSalesFinishDto;
@ -96,6 +98,9 @@ public class SysSalesOrderController extends BaseController
@Autowired
private ISysSalesOrderChildService sysSalesOrderChildService;
@Autowired
private IFinancialTaxInvoiceService taxInvoiceService;
@RequiresPermissions("system:salesOrder:view")
@GetMapping()
public String salesOrder(ModelMap mmap)
@ -583,4 +588,35 @@ public class SysSalesOrderController extends BaseController
return prefix + "/startAftersalesMaterialSelect";
}
/**
* 加载开票弹窗
*/
@GetMapping("/makeInvoice/{salesOrderId}")
public String makeInvoice(@PathVariable("salesOrderId") Long salesOrderId, ModelMap mmap)
{
SysSalesOrder sysSalesOrder = sysSalesOrderService.selectSysSalesOrderById(salesOrderId);
String commonCurrency = sysSalesOrder.getCommonCurrency();
FinancialTaxInvoice taxInvoice = taxInvoiceService.fillInvoiceBySalesOrder(sysSalesOrder);
mmap.put("taxInvoice", taxInvoice);
if ("1".equals(commonCurrency)){
return prefix + "/makeInvoiceRMB";
}else {
return prefix + "/makeInvoiceUSD";
}
}
/**
* 新增开票
*/
@RequiresPermissions("system:salesOrder:makeInvoice")
@Log(title = "销售订单", businessType = BusinessType.MakeInvoice)
@PostMapping("/makeInvoice")
@ResponseBody
public AjaxResult makeInvoiceSave(FinancialTaxInvoice financialTaxInvoice)
{
return toAjax(taxInvoiceService.makeInvoiceSave(financialTaxInvoice));
}
}

1
ruoyi-admin/src/main/resources/mapper/system/SysSalesOrderMapper.xml

@ -123,6 +123,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="makeStatus != null and makeStatus != ''"> and s.make_status = #{makeStatus}</if>
<if test="deliveryStatus != null and deliveryStatus != ''"> and s.delivery_status = #{deliveryStatus}</if>
<if test="closeStatus != null and closeStatus != ''"> and s.close_status = #{closeStatus}</if>
<if test="invoice != null and invoice != ''"> and s.invoice = #{invoice}</if>
<if test="instanceType != null and instanceType != ''"> and s.instance_type = #{instanceType}</if>
<if test="instanceId != null and instanceId != ''"> and s.instance_id = #{instanceId}</if>
<if test="applyUser != null and applyUser != ''"> and s.apply_user = #{applyUser}</if>

166
ruoyi-admin/src/main/resources/templates/system/salesOrder/makeInvoiceRMB.html

@ -0,0 +1,166 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('修改国税发票')" />
<th:block th:include="include :: datetimepicker-css" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-taxInvoice-RMBAdd" th:object="${taxInvoice}">
<input name="taxInvoiceId" th:field="*{taxInvoiceId}" type="hidden">
<div class="form-group">
<label class="col-sm-3 control-label">销售订单编号:</label>
<div class="col-sm-8">
<input name="salesOrderCode" th:field="*{salesOrderCode}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">订单类型:</label>
<div class="col-sm-8">
<select name="salesOrderType" class="form-control m-b" th:with="type=${@dict.getType('sys_order_type')}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{salesOrderType}"></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">报价币种:</label>
<div class="col-sm-8">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_common_currency')}">
<input type="radio" th:id="${'commonCurrency_' + dict.dictCode}" name="commonCurrency" th:value="${dict.dictValue}" th:field="*{commonCurrency}">
<label th:for="${'commonCurrency_' + dict.dictCode}" th:text="${dict.dictLabel}"></label>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">客户代码/ID:</label>
<div class="col-sm-8">
<input name="enterpriseCode" th:field="*{enterpriseCode}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">客户名称:</label>
<div class="col-sm-8">
<input name="enterpriseName" th:field="*{enterpriseName}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">联系电话:</label>
<div class="col-sm-8">
<input name="contactNumber" th:field="*{contactNumber}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">公司地址:</label>
<div class="col-sm-8">
<input name="enterpriseAddress" th:field="*{enterpriseAddress}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">开票公司名称:</label>
<div class="col-sm-8">
<input name="invoiceCompanyName" th:field="*{invoiceCompanyName}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">开票公司税号:</label>
<div class="col-sm-8">
<input name="invoiceCompanyCode" th:field="*{invoiceCompanyCode}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">公司开户行:</label>
<div class="col-sm-8">
<input name="depositBank" th:field="*{depositBank}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">公司开户账号:</label>
<div class="col-sm-8">
<input name="bankAccount" th:field="*{bankAccount}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">税率:</label>
<div class="col-sm-8">
<input name="taxRate" th:field="*{taxRate}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">发票种类:</label>
<div class="col-sm-8">
<select name="taxInvoiceClass" class="form-control m-b" th:with="type=${@dict.getType('tax_invoice_class')}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{taxInvoiceClass}"></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">发票类型:</label>
<div class="col-sm-8">
<select name="taxInvoiceType" class="form-control m-b" th:with="type=${@dict.getType('tax_invoice_type')}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{taxInvoiceType}"></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">发票抬头:</label>
<div class="col-sm-8">
<select name="taxInvoiceTitle" class="form-control m-b" th:with="type=${@dict.getType('tax_invoice_title')}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{taxInvoiceTitle}"></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">业务人员:</label>
<div class="col-sm-8">
<input name="businessMembers" th:field="*{businessMembers}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">申请人:</label>
<div class="col-sm-8">
<input name="applyUser" th:field="*{applyUser}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">邮箱:</label>
<div class="col-sm-8">
<input name="invoiceEmail" th:field="*{invoiceEmail}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">业务备注:</label>
<div class="col-sm-8">
<input name="businessRemark" th:field="*{businessRemark}" class="form-control" type="text">
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: datetimepicker-js" />
<script th:inline="javascript">
var prefix = ctx + "system/salesOrder"
$("#form-taxInvoice-RMBAdd").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/makeInvoice", $('#form-taxInvoice-RMBAdd').serialize());
}
}
$("input[name='invoiceData']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
});
</script>
</body>
</html>

52
ruoyi-admin/src/main/resources/templates/system/salesOrder/salesOrder.html

@ -159,6 +159,14 @@
th:value="${dict.dictValue}"></option>
</select>
</li>
<li>
<label>是否开票:</label>
<select name="invoice" th:with="type=${@dict.getType('sys_whether')}">
<option value="">所有</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}"
th:value="${dict.dictValue}"></option>
</select>
</li>
<li class="select-time">
<label>录入时间: </label>
<input type="text" class="time-input" id="startTime" placeholder="开始时间" name="params[beginTime]"/>
@ -180,6 +188,9 @@
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="system:salesOrder:add">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-success" onclick="makeInvoice()" shiro:hasPermission="system:salesOrder:makeInvoice">
<i class="fa fa-plus"></i> 开票
</a>
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table" style="white-space:nowrap"></table>
@ -208,6 +219,8 @@
var warehouseDeptDatas = [[${@dict.getType('warehouseDept')}]];
var closeStatusDatas = [[${@dict.getType('sys_close_status')}]];
var confirmTaxDatas = [[${@dict.getType('sys_confirm_tax')}]];
var sysWhetherDatas = [[${@dict.getType('sys_whether')}]];
var loginName = [[${@permission.getPrincipalProperty('loginName')}]];
var prefix = ctx + "system/salesOrder";
$(function () {
@ -288,6 +301,10 @@
}
},
{title: '业务人员',field: 'businessMembers',visible: false},
{title: '是否开票',field:'invoice',formatter:function(value, row, index){
return $.table.selectDictLabel(sysWhetherDatas, value);
}
},
{title: '销售单号',field: 'salesOrderCode'},
{title: '订单类型',field: 'salesOrderType',formatter: function(value, row, index) {
return $.table.selectDictLabel(salesOrderTypeDatas, value);
@ -393,6 +410,41 @@
var url = prefix + "/startAftersales/" + salesOrderId;
$.modal.open("售后",url);
}
//开票
function makeInvoice() {
// 获取选中的行
const selectedRows = $("#bootstrap-table").bootstrapTable('getSelections');
// 定义状态码常量
const AUDIT_STATUS_APPROVED = "1";//审核通过
const INVOICE_ALLOWED = "1";//允许开票
// 检查是否选择了恰好一行数据
if (selectedRows.length === 1) {
const row = selectedRows[0];
// 检查是否已审核
if (row.auditStatus === AUDIT_STATUS_APPROVED) {
// 检查是否允许开票
if (row.invoice === INVOICE_ALLOWED) {
const invoiceUrl = prefix + "/makeInvoice/" + row.salesOrderId;
$.modal.open("开票", invoiceUrl);
} else {
showWarning("该订单不允许开票");
}
} else {
showWarning("请先审核");
}
} else {
showWarning("请先选择一条销售订单");
}
}
// 显示警告消息的通用函数
function showWarning(message) {
$.modal.msgWarning(message);
}
</script>
</body>
</html>

Loading…
Cancel
Save