Browse Source

[feat] 销售管理

按照万材要求,销售管理销售估价单新增导出功能,支持部分行和全部行导出,导出更多数据
新增 销售管理销售估价单导出明细实体类
新增导出所有和选择导出后端接口
新增 导出销售估价单单明细方法
新增 根据销售估价单号数组查询销售估价单集合方法
新增 根据销售估价单号集合查询销售估价单详情数据方法
dev
liuxiaoxu 5 days ago
parent
commit
b20c7e3376
  1. 29
      ruoyi-admin/src/main/java/com/ruoyi/sales/controller/SalesEstimateController.java
  2. 2
      ruoyi-admin/src/main/java/com/ruoyi/sales/domain/SalesEstimateDetail.java
  3. 164
      ruoyi-admin/src/main/java/com/ruoyi/sales/domain/VO/ExportSalesEstimateDetailVo.java
  4. 5
      ruoyi-admin/src/main/java/com/ruoyi/sales/mapper/SalesEstimateDetailMapper.java
  5. 5
      ruoyi-admin/src/main/java/com/ruoyi/sales/mapper/SalesEstimateMapper.java
  6. 11
      ruoyi-admin/src/main/java/com/ruoyi/sales/service/ISalesEstimateService.java
  7. 94
      ruoyi-admin/src/main/java/com/ruoyi/sales/service/impl/SalesEstimateServiceImpl.java
  8. 8
      ruoyi-admin/src/main/resources/mapper/sales/SalesEstimateDetailMapper.xml
  9. 10
      ruoyi-admin/src/main/resources/mapper/sales/SalesEstimateMapper.xml
  10. 59
      ruoyi-admin/src/main/resources/templates/sales/estimate/estimate.html

29
ruoyi-admin/src/main/java/com/ruoyi/sales/controller/SalesEstimateController.java

@ -8,6 +8,7 @@ import com.ruoyi.erp.service.IErpMaterialService;
import com.ruoyi.sales.domain.SalesEstimateDetail;
import com.ruoyi.sales.domain.SalesEstimateDetailMaterial;
import com.ruoyi.sales.domain.SalesEstimateTemplate;
import com.ruoyi.sales.domain.VO.ExportSalesEstimateDetailVo;
import com.ruoyi.sales.domain.VO.SalesEstimateDetailMaterialVo;
import com.ruoyi.sales.domain.VO.SalesEstimateDetailVo;
import com.ruoyi.sales.service.ISalesEstimateDetailMaterialService;
@ -82,15 +83,35 @@ public class SalesEstimateController extends BaseController
*/
@RequiresPermissions("sales:estimate:export")
@Log(title = "销售估价", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@PostMapping("/exportAll")
@ResponseBody
public AjaxResult export(SalesEstimate salesEstimate)
public AjaxResult exportAll(SalesEstimate salesEstimate)
{
List<SalesEstimate> list = salesEstimateService.selectSalesEstimateList(salesEstimate);
ExcelUtil<SalesEstimate> util = new ExcelUtil<SalesEstimate>(SalesEstimate.class);
return util.exportExcel(list, "销售估价数据");
List<ExportSalesEstimateDetailVo> exportSalesEstimateDetailVos = salesEstimateService.exportSalesEstimateList(list);
ExcelUtil<ExportSalesEstimateDetailVo> util = new ExcelUtil<ExportSalesEstimateDetailVo>(ExportSalesEstimateDetailVo.class);
return util.exportExcel(exportSalesEstimateDetailVos, "销售估价数据");
}
/**
* 导出销售估价列表
*/
@RequiresPermissions("sales:estimate:export")
@Log(title = "销售估价", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(@RequestBody String[] salesEstimateCodes)
{
List<SalesEstimate> list = salesEstimateService.selectSalesEstimateListByCodes(salesEstimateCodes);
List<ExportSalesEstimateDetailVo> exportSalesEstimateDetailVos = salesEstimateService.exportSalesEstimateList(list);
ExcelUtil<ExportSalesEstimateDetailVo> util = new ExcelUtil<ExportSalesEstimateDetailVo>(ExportSalesEstimateDetailVo.class);
return util.exportExcel(exportSalesEstimateDetailVos, "销售估价数据");
}
/**
* 新增销售估价-业务
*/

2
ruoyi-admin/src/main/java/com/ruoyi/sales/domain/SalesEstimateDetail.java

@ -26,7 +26,7 @@ public class SalesEstimateDetail extends BaseEntity
private String salesEstimateCode;
/** 料号档位(0A、1B、2C、3D、4E、5F) */
@Excel(name = "料号档位", readConverterExp = "0=A、1B、2C、3D、4E、5F")
@Excel(name = "料号档位", dictType = "material_gear_position")
private String materialGearPosition;
/** 美元汇率 */

164
ruoyi-admin/src/main/java/com/ruoyi/sales/domain/VO/ExportSalesEstimateDetailVo.java

@ -0,0 +1,164 @@
package com.ruoyi.sales.domain.VO;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class ExportSalesEstimateDetailVo {
/** 估价单号 */
@Excel(name = "估价单号")
private String salesEstimateCode;
/** 业务人员 */
@Excel(name = "业务人员")
private String businessMembers;
/** 估价状态(0待工程、1待采购、2待总经理、3已完成) */
@Excel(name = "估价状态", dictType = "estimate_status")
private String estimateStatus;
/** 客户代码id */
@Excel(name = "客户代码id")
private String enterpriseCode;
/** 客户名称 */
@Excel(name = "客户名称")
private String enterpriseName;
/** 物料合计 */
@Excel(name = "物料合计")
private Long materialSum;
/** 数量合计 */
@Excel(name = "数量合计")
private Long enterpriseSum;
/** 估价币种(1RMB、2美元) */
@Excel(name = "估价币种", dictType = "sys_common_currency")
private String commonCurrency;
/** 不含税单价(RMB) */
private BigDecimal noTaxRmb;
/** 含税单价(RMB) */
private BigDecimal taxRmb;
/** 不含税总价(RMB) */
@Excel(name = "不含税总价")
private BigDecimal allNoTaxRmb;
/** 含税总价(RMB) */
@Excel(name = "含税总价")
private BigDecimal allTaxRmb;
/** 含税单价(美元) */
private BigDecimal taxDollar;
/** 不含税单价(美元) */
private BigDecimal noTaxDollar;
/** 含税总价(美元) */
@Excel(name = "含税总价")
private BigDecimal allTaxDollar;
/** 不含税总价(美元) */
@Excel(name = "不含税总价")
private BigDecimal allNoTaxDollar;
/** 定价日期 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "定价日期")
private Date pricingDate;
/** 料号档位(0A、1B、2C、3D、4E、5F) */
@Excel(name = "料号档位", dictType = "material_gear_position")
private String materialGearPosition;
/** 美元汇率 */
@Excel(name = "美元汇率")
private BigDecimal usdRate;
/** 利润率 */
@Excel(name = "利润率")
private BigDecimal profitRate;
/** 料号 */
@Excel(name = "料号")
private String materialNo;
/** 物料名称 */
@Excel(name = "物料名称")
private String materialName;
/** 物料类型 */
@Excel(name = "物料类型")
private String materialType;
/** 图片地址 */
@Excel(name = "图片地址")
private String materialPhotoUrl;
/** 物料单位 */
@Excel(name = "物料单位")
private String materialUnit;
/** 物料品牌 */
@Excel(name = "物料品牌")
private String materialBrand;
/** 物料描述 */
@Excel(name = "物料描述")
private String materialDescribe;
/** 加工方式 */
@Excel(name = "加工方式")
private String materialProcessMethod;
/** 物料数量 */
@Excel(name = "物料数量")
private Long materialNum;
/** 不含税运输成本(RMB) */
private BigDecimal noTaxShippingCosts;
/** 不含税服务成本(RMB) */
private BigDecimal noTaxServiceCosts;
/** 不含税开发成本(RMB) */
private BigDecimal noTaxDevelopCosts;
/** 不含税人工成本(RMB) */
private BigDecimal noTaxLaborCosts;
/** 不含税推广成本(RMB) */
private BigDecimal noTaxPromotionalCosts;
/** 不含税业务成本(RMB) */
private BigDecimal noTaxBusinessCosts;
/** 不含税管理成本(RMB) */
private BigDecimal noTaxManagesCosts;
/** 不含税总物料成本(RMB) */
private BigDecimal noTaxMaterialCosts;
/** 不含税经营成本(RMB) */
private BigDecimal noTaxOperatingCosts;
/** 含税经营成本(RMB) */
private BigDecimal taxOperatingCosts;
/** 上一年度不含税总经营成本(RMB) */
private BigDecimal totalOperatingCosts;
}

5
ruoyi-admin/src/main/java/com/ruoyi/sales/mapper/SalesEstimateDetailMapper.java

@ -95,4 +95,9 @@ public interface SalesEstimateDetailMapper
* 检查销售估价子表是否引用了物料
* */
int checkMaterialIsReferencedByEstimateDetail(String materialNo);
/**
* 根据销售估价编号集合查询销售估价子表
* */
List<SalesEstimateDetail> selectEstimateDetailListByCodes(List<String> collectSalesEstimateCodes);
}

5
ruoyi-admin/src/main/java/com/ruoyi/sales/mapper/SalesEstimateMapper.java

@ -82,4 +82,9 @@ public interface SalesEstimateMapper
* @return 结果
*/
public int restoreSalesEstimateById(Long salesEstimateId);
/**
* 根据编码查询销售估价
* */
List<SalesEstimate> selectSalesEstimateListByCodes(String[] salesEstimateCodes);
}

11
ruoyi-admin/src/main/java/com/ruoyi/sales/service/ISalesEstimateService.java

@ -2,6 +2,7 @@ package com.ruoyi.sales.service;
import java.util.List;
import com.ruoyi.sales.domain.SalesEstimate;
import com.ruoyi.sales.domain.VO.ExportSalesEstimateDetailVo;
import com.ruoyi.sales.domain.VO.SalesEstimateDetailVo;
/**
@ -107,4 +108,14 @@ public interface ISalesEstimateService
* @return
*/
int updateSalesEstimateSave(SalesEstimate salesEstimate);
/**
* 导出销售估价明细
* */
List<ExportSalesEstimateDetailVo> exportSalesEstimateList(List<SalesEstimate> list);
/**
* 根据销售估价编号查询销售估价
* */
List<SalesEstimate> selectSalesEstimateListByCodes(String[] salesEstimateCodes);
}

94
ruoyi-admin/src/main/java/com/ruoyi/sales/service/impl/SalesEstimateServiceImpl.java

@ -2,18 +2,16 @@ package com.ruoyi.sales.service.impl;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.sales.domain.SalesEstimateDetail;
import com.ruoyi.sales.domain.SalesEstimateDetailMaterial;
import com.ruoyi.sales.domain.SalesEstimateTemplate;
import com.ruoyi.sales.domain.*;
import com.ruoyi.sales.domain.VO.ExportSalesEstimateDetailVo;
import com.ruoyi.sales.domain.VO.SalesEstimateDetailVo;
import com.ruoyi.sales.mapper.SalesEstimateDetailMapper;
import com.ruoyi.sales.mapper.SalesEstimateDetailMaterialMapper;
@ -21,7 +19,6 @@ import com.ruoyi.sales.mapper.SalesEstimateTemplateMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.sales.mapper.SalesEstimateMapper;
import com.ruoyi.sales.domain.SalesEstimate;
import com.ruoyi.sales.service.ISalesEstimateService;
import com.ruoyi.common.core.text.Convert;
import org.springframework.transaction.annotation.Transactional;
@ -297,6 +294,89 @@ public class SalesEstimateServiceImpl implements ISalesEstimateService
return salesEstimateMapper.updateSalesEstimate(salesEstimate);
}
/**
* 导出销售估价明细
* */
@Override
public List<ExportSalesEstimateDetailVo> exportSalesEstimateList(List<SalesEstimate> list) {
// 获取所有的估价单号
List<String> collectSalesEstimateCodes = list.stream().map(SalesEstimate::getSalesEstimateCode).collect(Collectors.toList());
// 根据估价单号查询对应的详情列表
List<SalesEstimateDetail> salesEstimateDetailList = salesEstimateDetailMapper.selectEstimateDetailListByCodes(collectSalesEstimateCodes);
// 创建一个估价VO的Map,键为估价单号
Map<String, SalesEstimate> salesEstimateMap = list.stream()
.collect(Collectors.toMap(SalesEstimate::getSalesEstimateCode, Function.identity()));
// 初始化导出列表
List<ExportSalesEstimateDetailVo> exportSalesEstimateDetailVos = new ArrayList<>();
for (SalesEstimateDetail detail : salesEstimateDetailList) {
ExportSalesEstimateDetailVo exportVo = new ExportSalesEstimateDetailVo();
// 从SalesEstimateDetail填充数据
exportVo.setMaterialGearPosition(detail.getMaterialGearPosition());
exportVo.setUsdRate(detail.getUsdRate());
exportVo.setProfitRate(detail.getProfitRate());
exportVo.setMaterialNo(detail.getMaterialNo());
exportVo.setMaterialName(detail.getMaterialName());
exportVo.setMaterialType(detail.getMaterialType());
exportVo.setMaterialPhotoUrl(detail.getMaterialPhotoUrl());
exportVo.setMaterialUnit(detail.getMaterialUnit());
exportVo.setMaterialBrand(detail.getMaterialBrand());
exportVo.setMaterialDescribe(detail.getMaterialDescribe());
exportVo.setMaterialProcessMethod(detail.getMaterialProcessMethod());
exportVo.setMaterialNum(detail.getMaterialNum());
exportVo.setNoTaxShippingCosts(detail.getNoTaxShippingCosts());
exportVo.setNoTaxServiceCosts(detail.getNoTaxServiceCosts());
exportVo.setNoTaxDevelopCosts(detail.getNoTaxDevelopCosts());
exportVo.setNoTaxLaborCosts(detail.getNoTaxLaborCosts());
exportVo.setNoTaxPromotionalCosts(detail.getNoTaxPromotionalCosts());
exportVo.setNoTaxBusinessCosts(detail.getNoTaxBusinessCosts());
exportVo.setNoTaxManagesCosts(detail.getNoTaxManagesCosts());
exportVo.setNoTaxMaterialCosts(detail.getNoTaxMaterialCosts());
exportVo.setNoTaxOperatingCosts(detail.getNoTaxOperatingCosts());
exportVo.setTaxOperatingCosts(detail.getTaxOperatingCosts());
exportVo.setTotalOperatingCosts(detail.getTotalOperatingCosts());
// 从SalesEstimate填充数据,通过估价单号进行关联
SalesEstimate estimate = salesEstimateMap.get(detail.getSalesEstimateCode());
if (estimate != null) {
exportVo.setSalesEstimateCode(estimate.getSalesEstimateCode());
exportVo.setBusinessMembers(estimate.getBusinessMembers());
exportVo.setEstimateStatus(estimate.getEstimateStatus());
exportVo.setEnterpriseCode(estimate.getEnterpriseCode());
exportVo.setEnterpriseName(estimate.getEnterpriseName());
exportVo.setMaterialSum(estimate.getMaterialSum());
exportVo.setEnterpriseSum(estimate.getEnterpriseSum());
exportVo.setCommonCurrency(estimate.getCommonCurrency());
exportVo.setNoTaxRmb(estimate.getNoTaxRmb());
exportVo.setTaxRmb(estimate.getTaxRmb());
exportVo.setAllNoTaxRmb(estimate.getAllNoTaxRmb());
exportVo.setAllTaxRmb(estimate.getAllTaxRmb());
exportVo.setTaxDollar(estimate.getTaxDollar());
exportVo.setNoTaxDollar(estimate.getNoTaxDollar());
exportVo.setAllTaxDollar(estimate.getAllTaxDollar());
exportVo.setAllNoTaxDollar(estimate.getAllNoTaxDollar());
exportVo.setPricingDate(estimate.getPricingDate());
}
// 添加到结果列表
exportSalesEstimateDetailVos.add(exportVo);
}
return exportSalesEstimateDetailVos;
}
/**
* 根据估价单号查询对应的详情列表
* */
@Override
public List<SalesEstimate> selectSalesEstimateListByCodes(String[] salesEstimateCodes) {
List<SalesEstimate> list = salesEstimateMapper.selectSalesEstimateListByCodes(salesEstimateCodes);
return list;
}
/* 下面的计算规则

8
ruoyi-admin/src/main/resources/mapper/sales/SalesEstimateDetailMapper.xml

@ -69,6 +69,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select count(1) from sales_estimate_detail where material_no = #{materialNo}
</select>
<select id="selectEstimateDetailListByCodes" parameterType="String" resultMap="SalesEstimateDetailResult">
<include refid="selectSalesEstimateDetailVo"/>
where sales_estimate_code in
<foreach collection="list" item="salesEstimateCode" index="index" open="(" separator="," close=")">
#{salesEstimateCode}
</foreach>
</select>
<insert id="insertSalesEstimateDetail" parameterType="SalesEstimateDetail" useGeneratedKeys="true" keyProperty="estimateDetailId">
insert into sales_estimate_detail
<trim prefix="(" suffix=")" suffixOverrides=",">

10
ruoyi-admin/src/main/resources/mapper/sales/SalesEstimateMapper.xml

@ -53,7 +53,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include refid="selectSalesEstimateVo"/>
where sales_estimate_id = #{salesEstimateId}
</select>
<select id="selectSalesEstimateListByCodes" parameterType="String" resultMap="SalesEstimateResult">
<include refid="selectSalesEstimateVo"/>
where sales_estimate_code in
<foreach item="salesEstimateCode" collection="array" open="(" separator="," close=")">
#{salesEstimateCode}
</foreach>
</select>
<insert id="insertSalesEstimate" parameterType="SalesEstimate" useGeneratedKeys="true" keyProperty="salesEstimateId">
insert into sales_estimate
<trim prefix="(" suffix=")" suffixOverrides=",">

59
ruoyi-admin/src/main/resources/templates/sales/estimate/estimate.html

@ -52,9 +52,14 @@
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="sales:estimate:add">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-success" onclick="exportExcel()" shiro:hasPermission="sales:estimate:export">
<i class="fa fa-download"></i> 导出
</a>
<a class="btn btn-success" onclick="addTemplate()" shiro:hasPermission="sales:estimate:addOperatingCostTemplate">
<i class="fa fa-plus"></i> 经营成本模板
</a>
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
@ -298,6 +303,60 @@
$.modal.open("详情", url);
}
// 导出
function exportExcel(formId) {
// $.table.set();
var salesEstimateCodeData = [];
var selections = $("#bootstrap-table").bootstrapTable("getSelections");
if(selections.length === 0){
$.modal.confirm("确定导出所有销售估价单吗?", function() {
var currentId = $.common.isEmpty(formId) ? $('form').attr('id') : formId;
var params = $("#bootstrap-table").bootstrapTable('getOptions');
var dataParam = $("#" + currentId).serializeArray();
dataParam.push({ "name": "orderByColumn", "value": params.sortName });
dataParam.push({ "name": "isAsc", "value": params.sortOrder });
$.modal.loading("正在导出数据,请稍后...");
$.post(prefix + '/exportAll', dataParam, function(result) {
if (result.code == web_status.SUCCESS) {
window.location.href = ctx + "common/download?fileName=" + encodeURI(result.msg) + "&delete=" + true;
} else if (result.code == web_status.WARNING) {
$.modal.alertWarning(result.msg)
} else {
$.modal.alertError(result.msg);
}
$.modal.closeLoading();
});
});
}else {
$.modal.confirm("确定导出选中的所有销售估价单吗?", function () {
//·拼接单号
for(let i=0;i<selections.length;i++){
salesEstimateCodeData.push(selections[i].salesEstimateCode);
}
var salesEstimateCodes = JSON.stringify(salesEstimateCodeData);
// console.log(bomNos);
$.modal.loading("正在导出数据,请稍后...");
var config = {
url: prefix + '/export',
type: "post",
dataType: "json",
contentType: "application/json;charset=utf-8",
data: salesEstimateCodes,
success: function(result) {
window.location.href = ctx + "common/download?fileName=" + encodeURI(result.msg) + "&delete=" + true;
$.modal.alertSuccess("导出成功!")
$.modal.closeLoading();
},
error: function (result){
$.modal.alertError(result.msg);
}
};
$.ajax(config)
});
}
};
</script>
</body>
</html>
Loading…
Cancel
Save