Browse Source

[feat] 销售管理

修改工程添加物料页面:新增销售估价详情ID字段;修改提交方法:新增运输、服务、开发成本等字段;新增遍历每个子表数据,如果有任何字段为空,就进行提示,阻止提交操作;新增展缩子表物料数据;新增展缩子表的时候动态生成运输、服务、开发成本等form表单
新增 根据销售估价详情ID获取销售估价详情物料价格集合后端接口
新增 销售估价详情子表物料数据集合展示后端接口
新增 工程添加销售估价后端接口
dev
liuxiaoxu 7 months ago
parent
commit
54e6c71e03
  1. 15
      ruoyi-admin/src/main/java/com/ruoyi/sales/controller/SalesEstimateController.java
  2. 8
      ruoyi-admin/src/main/java/com/ruoyi/sales/mapper/SalesEstimateDetailMaterialMapper.java
  3. 7
      ruoyi-admin/src/main/java/com/ruoyi/sales/service/ISalesEstimateDetailMaterialService.java
  4. 6
      ruoyi-admin/src/main/java/com/ruoyi/sales/service/ISalesEstimateService.java
  5. 14
      ruoyi-admin/src/main/java/com/ruoyi/sales/service/impl/SalesEstimateDetailMaterialServiceImpl.java
  6. 28
      ruoyi-admin/src/main/java/com/ruoyi/sales/service/impl/SalesEstimateServiceImpl.java
  7. 5
      ruoyi-admin/src/main/resources/mapper/sales/SalesEstimateDetailMaterialMapper.xml
  8. 100
      ruoyi-admin/src/main/resources/templates/sales/estimate/engineeringAdd.html

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

@ -138,7 +138,7 @@ public class SalesEstimateController extends BaseController
@ResponseBody @ResponseBody
public AjaxResult engineeringAddSave(@RequestBody SalesEstimate salesEstimate) public AjaxResult engineeringAddSave(@RequestBody SalesEstimate salesEstimate)
{ {
return toAjax(salesEstimateService.insertSalesEstimate(salesEstimate)); return toAjax(salesEstimateService.engineeringAddSalesEstimate(salesEstimate));
} }
@ -155,6 +155,19 @@ public class SalesEstimateController extends BaseController
return getDataTable(list); return getDataTable(list);
} }
/**
* 销售估价详情子表物料数据集合展示
*/
@ResponseBody
@PostMapping("/getEstimateDetailMaterialList")
public TableDataInfo getEstimateDetailMaterialList(@RequestParam("estimateDetailId") Long estimateDetailId )
{
startPage();
List<SalesEstimateDetailMaterial> list = estimateDetailMaterialService.getEstimateDetailMaterialList(estimateDetailId);
return getDataTable(list);
}
/** /**
* 加载新增销售估价-工程 子表物料选择弹窗 * 加载新增销售估价-工程 子表物料选择弹窗

8
ruoyi-admin/src/main/java/com/ruoyi/sales/mapper/SalesEstimateDetailMaterialMapper.java

@ -84,4 +84,12 @@ public interface SalesEstimateDetailMaterialMapper
* @return 结果 * @return 结果
*/ */
public int restoreSalesEstimateDetailMaterialById(Long estimateDetailMaterialId); public int restoreSalesEstimateDetailMaterialById(Long estimateDetailMaterialId);
/**
* 根据estimateDetailId查询详情物料价格
*
* @param estimateDetailId 销售估价详情物料价格ID
* @return 结果
*/
List<SalesEstimateDetailMaterial> selectDetailMaterialListByEstimateDetailId(Long estimateDetailId);
} }

7
ruoyi-admin/src/main/java/com/ruoyi/sales/service/ISalesEstimateDetailMaterialService.java

@ -81,4 +81,11 @@ public interface ISalesEstimateDetailMaterialService
* @return * @return
*/ */
int insertEstimateDetailMaterialList(SalesEstimateDetail salesEstimateDetail); int insertEstimateDetailMaterialList(SalesEstimateDetail salesEstimateDetail);
/**
* 根据销售估价详情ID获取销售估价详情物料价格集合
* @param estimateDetailId 销售估价详情ID
* @return
*/
List<SalesEstimateDetailMaterial> getEstimateDetailMaterialList(Long estimateDetailId);
} }

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

@ -80,4 +80,10 @@ public interface ISalesEstimateService
*/ */
SalesEstimateDetailVo getSalesEstimateDetailVo(); SalesEstimateDetailVo getSalesEstimateDetailVo();
/**
* 工程添加销售估价
* @param salesEstimate
* @return
*/
int engineeringAddSalesEstimate(SalesEstimate salesEstimate);
} }

14
ruoyi-admin/src/main/java/com/ruoyi/sales/service/impl/SalesEstimateDetailMaterialServiceImpl.java

@ -48,6 +48,19 @@ public class SalesEstimateDetailMaterialServiceImpl implements ISalesEstimateDet
return salesEstimateDetailMaterialMapper.selectSalesEstimateDetailMaterialList(salesEstimateDetailMaterial); return salesEstimateDetailMaterialMapper.selectSalesEstimateDetailMaterialList(salesEstimateDetailMaterial);
} }
/**
* 查询销售估价详情物料价格列表
*
* @param estimateDetailId 销售估价详情物料价格ID
* @return 销售估价详情物料价格
*/
@Override
public List<SalesEstimateDetailMaterial> getEstimateDetailMaterialList(Long estimateDetailId) {
return salesEstimateDetailMaterialMapper.selectDetailMaterialListByEstimateDetailId(estimateDetailId);
}
/** /**
* 新增销售估价详情物料价格 * 新增销售估价详情物料价格
* *
@ -97,6 +110,7 @@ public class SalesEstimateDetailMaterialServiceImpl implements ISalesEstimateDet
return salesEstimateDetailMaterialMapper.insertSalesEstimateDetailMaterialBatch(salesEstimateDetailMaterialList); return salesEstimateDetailMaterialMapper.insertSalesEstimateDetailMaterialBatch(salesEstimateDetailMaterialList);
} }
/** /**
* 删除销售估价详情物料价格对象 * 删除销售估价详情物料价格对象
* *

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

@ -18,6 +18,7 @@ import com.ruoyi.sales.mapper.SalesEstimateMapper;
import com.ruoyi.sales.domain.SalesEstimate; import com.ruoyi.sales.domain.SalesEstimate;
import com.ruoyi.sales.service.ISalesEstimateService; import com.ruoyi.sales.service.ISalesEstimateService;
import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.core.text.Convert;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
/** /**
@ -190,4 +191,31 @@ public class SalesEstimateServiceImpl implements ISalesEstimateService
salesEstimateDetailVo.setNoTaxMaterialCosts(salesEstimateTemplate.getNoTaxMaterialCosts()); salesEstimateDetailVo.setNoTaxMaterialCosts(salesEstimateTemplate.getNoTaxMaterialCosts());
return salesEstimateDetailVo; return salesEstimateDetailVo;
} }
/**
* 工程添加销售估价
*
* @param salesEstimate 销售估价
* @return 结果
*/
@Transactional(rollbackFor = Exception.class)
@Override
public int engineeringAddSalesEstimate(SalesEstimate salesEstimate) {
String loginName = ShiroUtils.getLoginName();
salesEstimate.setUpdateBy(loginName);
salesEstimate.setUpdateTime(new Date());
salesEstimate.setEstimateStatus("1");
List<SalesEstimateDetail> salesEstimateDetailList = salesEstimate.getSalesEstimateDetailList();
for (SalesEstimateDetail salesEstimateDetail : salesEstimateDetailList) {
salesEstimateDetail.setUpdateBy(loginName);
salesEstimateDetail.setUpdateTime(new Date());
int updateDetailResult = salesEstimateDetailMapper.updateSalesEstimateDetail(salesEstimateDetail);
if (updateDetailResult == 0){
throw new BusinessException("更新销售估价详情失败");
}
}
return salesEstimateMapper.updateSalesEstimate(salesEstimate);
}
} }

5
ruoyi-admin/src/main/resources/mapper/sales/SalesEstimateDetailMaterialMapper.xml

@ -41,6 +41,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where estimate_detail_material_id = #{estimateDetailMaterialId} where estimate_detail_material_id = #{estimateDetailMaterialId}
</select> </select>
<select id="selectDetailMaterialListByEstimateDetailId" parameterType="Long" resultMap="SalesEstimateDetailMaterialResult">
<include refid="selectSalesEstimateDetailMaterialVo"/>
where estimate_detail_id = #{estimateDetailId}
</select>
<insert id="insertSalesEstimateDetailMaterial" parameterType="SalesEstimateDetailMaterial" useGeneratedKeys="true" keyProperty="estimateDetailMaterialId"> <insert id="insertSalesEstimateDetailMaterial" parameterType="SalesEstimateDetailMaterial" useGeneratedKeys="true" keyProperty="estimateDetailMaterialId">
insert into sales_estimate_detail_material insert into sales_estimate_detail_material
<trim prefix="(" suffix=")" suffixOverrides=","> <trim prefix="(" suffix=")" suffixOverrides=",">

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

@ -7,6 +7,7 @@
<body class="white-bg"> <body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content"> <div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-estimate-add" th:object="${salesEstimate}"> <form class="form-horizontal m" id="form-estimate-add" th:object="${salesEstimate}">
<input name="salesEstimateId" th:field="*{salesEstimateId}" type="hidden">
<div class="form-group"> <div class="form-group">
<label class="col-sm-4 control-label">业务员:</label> <label class="col-sm-4 control-label">业务员:</label>
<div class="col-sm-8"> <div class="col-sm-8">
@ -118,50 +119,59 @@
return obj; return obj;
}, {}); }, {});
//设置一个标志来跟踪任何错误
var hasError = false;
// 销售估价物料 // 销售估价物料
var estimateMaterialTable = $('#bootstrap-table').bootstrapTable('getData'); var estimateMaterialTable = $('#bootstrap-table').bootstrapTable('getData');
if (estimateMaterialTable.length === 0){
$.modal.alertWarning("请至少添加一条物料信息");
return;
}
// 将表数据转换成与estimateData格式一致的数组 // 将表数据转换成与estimateData格式一致的数组
var estimateMaterialDataList = estimateMaterialTable.map(function(item) { var estimateMaterialDataList = estimateMaterialTable.map(function(item) {
// 根据实际字段名调整 // 根据实际字段名调整
return { return {
"materialNo": item.materialNo, "estimateDetailId": item.estimateDetailId,
"materialName": item.materialName, "noTaxDevelopCosts": null, // 初始化为 null 或 0
"materialType": item.materialType, "noTaxShippingCosts": null,
"materialPhotourl": item.materialPhotourl, "noTaxServiceCosts": null,
"materialDescribe": item.materialDescribe,
"materialBrand": item.materialBrand,
"materialUnit": item.materialUnit,
"materialProcessMethod": item.materialProcessMethod,
"materialGearPosition": item.materialGearPosition,
"materialNum":item.materialNum,
"noTaxRmb": item.noTaxRmb,
"taxRmb": item.taxRmb,
"allNoTaxRmb": item.allNoTaxRmb,
"allTaxRmb": item.allTaxRmb,
"noTaxDollar": item.noTaxDollar,
"taxDollar": item.taxDollar,
"allNoTaxDollar": item.allNoTaxDollar,
"allTaxDollar": item.allTaxDollar,
"warehouseDept": item.warehouseDept,
// ...其他字段 // ...其他字段
}; };
}); });
// 获取料号档位的最新值 $('.form-inline[data-index]').each(function () {
$('.form-control[id^="materialGearPosition_"]').each(function() { var index = $(this).data('index'); // 获取数据索引
const index = $(this).attr('id').match(/materialGearPosition_(\d+)/)[1]; // 提取索引 var noTaxDevelopCosts = $('#noTaxDevelopCosts' + index).val();
const value = $(this).val(); // 获取下拉框的值 var noTaxShippingCosts = $('#noTaxShippingCosts' + index).val();
estimateMaterialDataList[index].materialGearPosition = value; // 更新料号档位 var noTaxServiceCosts = $('#noTaxServiceCosts' + index).val();
// 检查成本值是否为空或仅为0
if (!noTaxDevelopCosts && noTaxDevelopCosts !== '0') {
$.modal.alertWarning("开发成本不能为空,请填写第 " + (parseInt(index) + 1) + " 行的开发成本");
hasError = true;
return; // 退出循环,阻止进一步处理
}
if (!noTaxShippingCosts && noTaxShippingCosts !== '0') {
$.modal.alertWarning("运输成本不能为空,请填写第 " + (parseInt(index) + 1) + " 行的运输成本");
hasError = true;
return; // 退出循环,阻止进一步处理
}
if (!noTaxServiceCosts && noTaxServiceCosts !== '0') {
$.modal.alertWarning("服务成本不能为空,请填写第 " + (parseInt(index) + 1) + " 行的服务成本");
hasError = true;
return; // 退出循环,阻止进一步处理
}
// 更新 estimateMaterialDataList 中对应的记录
estimateMaterialDataList[index].noTaxDevelopCosts = noTaxDevelopCosts;
estimateMaterialDataList[index].noTaxShippingCosts = noTaxShippingCosts;
estimateMaterialDataList[index].noTaxServiceCosts = noTaxServiceCosts;
}); });
if (hasError) {
return; // 存在错误,阻止提交
}
const combinedData = Object.assign({}, estimateData, { const combinedData = Object.assign({}, estimateData, {
salesEstimateDetailList: estimateMaterialDataList, salesEstimateDetailList: estimateMaterialDataList,
}); });
@ -170,7 +180,7 @@
// 使用 JSON.stringify() 序列化数据 // 使用 JSON.stringify() 序列化数据
const jsonData = JSON.stringify(combinedData); const jsonData = JSON.stringify(combinedData);
// 发送 AJAX 请求到后端接口 // 发送 AJAX 请求到后端接口
$.operate.saveJson(prefix + "/add", jsonData); $.operate.saveJson(prefix + "/engineeringAdd", jsonData);
} }
} }
@ -316,15 +326,12 @@
var childTableId = 'child_table_'+index; var childTableId = 'child_table_'+index;
$detail.html('<table id="'+childTableId+'"></table>'); $detail.html('<table id="'+childTableId+'"></table>');
$('#'+childTableId).bootstrapTable({ $('#'+childTableId).bootstrapTable({
url: prefix + "/showAftersalesShippingDeviceListTwo", url: prefix + "/getEstimateDetailMaterialList",
method: 'post', method: 'post',
sidePagination: "server", sidePagination: "server",
contentType: "application/x-www-form-urlencoded", contentType: "application/x-www-form-urlencoded",
queryParams : { queryParams : {
// salesOrderCode: warehouseOutOrder.salesOrderCode, estimateDetailId:parentRow.estimateDetailId
materialNo: parentRow.materialNo,
salesOrderCode:warehouseOutOrder.salesOrderCode,
makeNo:warehouseOutOrder.makeNo
}, },
columns: [ columns: [
{ {
@ -366,10 +373,19 @@
}); });
// 动态生成 form 表单 // 动态生成 form 表单
var formHtml = '<form class="form-inline">'; var formHtml = '<form class="form-inline" data-index="' + index + '">';
formHtml += '<h3>运输、服务、开发成本</h3>';
formHtml += '<div class="form-group">';
formHtml += '<label for="noTaxDevelopCosts' + index + '">不含税开发成本(RMB):</label>';
formHtml += '<input type="text" class="form-control" id="noTaxDevelopCosts' + index + '" name="noTaxDevelopCosts' + index + '" placeholder="请输入开发成本">';
formHtml += '</div>';
formHtml += '<div class="form-group">';
formHtml += '<label for="noTaxShippingCosts' + index + '">不含税运输成本(RMB):</label>';
formHtml += '<input type="text" class="form-control" id="noTaxShippingCosts' + index + '" name="noTaxShippingCosts' + index + '" placeholder="请输入运输成本">';
formHtml += '</div>';
formHtml += '<div class="form-group">'; formHtml += '<div class="form-group">';
formHtml += '<label for="additionalInput' + index + '">附加输入:</label>'; formHtml += '<label for="noTaxServiceCosts' + index + '">不含税服务成本(RMB):</label>';
formHtml += '<input type="text" class="form-control" id="additionalInput' + index + '" placeholder="请输入附加信息">'; formHtml += '<input type="text" class="form-control" id="noTaxServiceCosts' + index + '" name="noTaxServiceCosts' + index + '" placeholder="请输入服务成本">';
formHtml += '</div>'; formHtml += '</div>';
formHtml += '</form>'; formHtml += '</form>';
@ -386,7 +402,13 @@ function queryParams(params) {
} }
// 假设这是一个方法,用于获取所有展开行的索引
function getExpandedRowsIndexes() {
var rows = $('#bootstrap-table').bootstrapTable('getSelections');
return rows.map(function(row, index) {
return index; // 这里假设 index 是在 `onExpandRow` 中设置的
});
}
// 逻辑删除前端的一行数据 // 逻辑删除前端的一行数据

Loading…
Cancel
Save