Browse Source

[feat] 销售管理

修改添加添加估价-业务前端页面:所有字段加上非空校验,都设置为必填选项
新增业务员的值为:自动获取登录人
新增添加添加估价-业务前端页面的主子表提交方法
修改table种的料号档位为下拉框
新增添加物料信息的时候进行判断:不能添加相同物料号
新增 getTotalAmount函数:计算物料种类和物料数量的值
新增 销售估价详情Vo类,结合模板类,计算利润率
修改新增销售估价-销售后端接口:新增销售估价状态的默认值,新增币种的默认值
新增查询销售估价Vo详情后端接口:任何角色添加销售估价首先都要查询销售估价Vo详情,如果没有值进行总经理先添加经营成本模板提示,如果有值,就把模板值赋值给销售估价详情Vo类
dev
liuxiaoxu 4 months ago
parent
commit
d20604cb6a
  1. 8
      ruoyi-admin/src/main/java/com/ruoyi/sales/controller/SalesEstimateController.java
  2. 28
      ruoyi-admin/src/main/java/com/ruoyi/sales/domain/VO/SalesEstimateDetailVo.java
  3. 8
      ruoyi-admin/src/main/java/com/ruoyi/sales/service/ISalesEstimateService.java
  4. 43
      ruoyi-admin/src/main/java/com/ruoyi/sales/service/impl/SalesEstimateServiceImpl.java
  5. 194
      ruoyi-admin/src/main/resources/templates/sales/estimate/add.html

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

@ -5,6 +5,7 @@ import java.util.List;
import com.ruoyi.erp.domain.ErpMaterialVo;
import com.ruoyi.erp.service.IErpMaterialService;
import com.ruoyi.sales.domain.SalesEstimateTemplate;
import com.ruoyi.sales.domain.VO.SalesEstimateDetailVo;
import com.ruoyi.sales.service.ISalesEstimateTemplateService;
import com.ruoyi.system.domain.SysMakeOrder;
import com.ruoyi.system.domain.SysSalesOrderChild;
@ -82,8 +83,10 @@ public class SalesEstimateController extends BaseController
* 新增销售估价-业务
*/
@GetMapping("/add")
public String add()
public String add(ModelMap map)
{
SalesEstimateDetailVo salesEstimateDetailVo = salesEstimateService.getSalesEstimateDetailVo();
map.put("salesEstimateDetailVo",salesEstimateDetailVo);
return prefix + "/add";
}
@ -100,9 +103,6 @@ public class SalesEstimateController extends BaseController
}
/**
* 加载新增销售估价 物料选择弹窗
*/

28
ruoyi-admin/src/main/java/com/ruoyi/sales/domain/VO/SalesEstimateDetailVo.java

@ -0,0 +1,28 @@
package com.ruoyi.sales.domain.VO;
import com.ruoyi.sales.domain.SalesEstimateDetail;
import lombok.Data;
import java.math.BigDecimal;
// 销售估价详情Vo类,结合模板类,计算利润率
@Data
public class SalesEstimateDetailVo extends SalesEstimateDetail {
/** A挡利润率 */
private BigDecimal aProfitRate;
/** B挡利润率 */
private BigDecimal bProfitRate;
/** C挡利润率 */
private BigDecimal cProfitRate;
/** D挡利润率 */
private BigDecimal dProfitRate;
/** E挡利润率 */
private BigDecimal eProfitRate;
/** F挡利润率 */
private BigDecimal fProfitRate;
}

8
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.SalesEstimateDetailVo;
/**
* 销售估价Service接口
@ -72,4 +73,11 @@ public interface ISalesEstimateService
* @return
*/
int restoreSalesEstimateById(Long salesEstimateId);
/**
* 获取销售估价Vo详情
* @return
*/
SalesEstimateDetailVo getSalesEstimateDetailVo();
}

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

@ -4,16 +4,21 @@ import java.util.Date;
import java.util.List;
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.SalesEstimateTemplate;
import com.ruoyi.sales.domain.VO.SalesEstimateDetailVo;
import com.ruoyi.sales.mapper.SalesEstimateDetailMapper;
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.util.CollectionUtils;
/**
* 销售估价Service业务层处理
@ -33,6 +38,9 @@ public class SalesEstimateServiceImpl implements ISalesEstimateService
@Autowired
private RedisCache redisCache;
@Autowired
private SalesEstimateTemplateMapper estimateTemplateMapper;
/**
* 查询销售估价
*
@ -72,8 +80,10 @@ public class SalesEstimateServiceImpl implements ISalesEstimateService
salesEstimate.setCreateBy(loginName);
salesEstimate.setCreateTime(new Date());
salesEstimate.setSalesEstimateCode(salesEstimateCode);
//设置状态为待工程
salesEstimate.setEstimateStatus("0");
//设置默认值为RMB
salesEstimate.setCommonCurrency("1");
List<SalesEstimateDetail> salesEstimateDetailList = salesEstimate.getSalesEstimateDetailList();
if (salesEstimateDetailList != null && salesEstimateDetailList.size() > 0) {
for (SalesEstimateDetail salesEstimateDetail : salesEstimateDetailList) {
@ -151,4 +161,33 @@ public class SalesEstimateServiceImpl implements ISalesEstimateService
{
return salesEstimateMapper.restoreSalesEstimateById(salesEstimateId);
}
/**
* 查询销售估价Vo详情
*
* @return 销售估价Vo详情
*/
@Override
public SalesEstimateDetailVo getSalesEstimateDetailVo() {
SalesEstimateDetailVo salesEstimateDetailVo = new SalesEstimateDetailVo();
List<SalesEstimateTemplate> estimateTemplateList = estimateTemplateMapper.selectEstimateTemplateList();
if (CollectionUtils.isEmpty(estimateTemplateList)){
throw new BusinessException("总经理先添加经营成本模板");
}
SalesEstimateTemplate salesEstimateTemplate = estimateTemplateList.get(0);
salesEstimateDetailVo.setAProfitRate(salesEstimateTemplate.getaProfitRate());
salesEstimateDetailVo.setBProfitRate(salesEstimateTemplate.getbProfitRate());
salesEstimateDetailVo.setCProfitRate(salesEstimateTemplate.getcProfitRate());
salesEstimateDetailVo.setDProfitRate(salesEstimateTemplate.getdProfitRate());
salesEstimateDetailVo.setEProfitRate(salesEstimateTemplate.geteProfitRate());
salesEstimateDetailVo.setFProfitRate(salesEstimateTemplate.getfProfitRate());
salesEstimateDetailVo.setNoTaxLaborCosts(salesEstimateTemplate.getNoTaxLaborCosts());
salesEstimateDetailVo.setNoTaxBusinessCosts(salesEstimateTemplate.getNoTaxBusinessCosts());
salesEstimateDetailVo.setNoTaxManagesCosts(salesEstimateTemplate.getNoTaxManagesCosts());
salesEstimateDetailVo.setNoTaxPromotionalCosts(salesEstimateTemplate.getNoTaxPromotionalCosts());
salesEstimateDetailVo.setNoTaxMaterialCosts(salesEstimateTemplate.getNoTaxMaterialCosts());
return salesEstimateDetailVo;
}
}

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

@ -10,7 +10,7 @@
<div class="form-group">
<label class="col-sm-4 control-label">业务员:</label>
<div class="col-sm-8">
<input name="businessMembers" class="form-control" type="text">
<input name="businessMembers" id="businessMembers" class="form-control" type="text" readonly>
</div>
</div>
<div class="form-group">
@ -37,10 +37,10 @@
</div>
</div>
<div class="form-group">
<div class="form-group">
<label class="col-sm-4 control-label is-required">估价币种:</label>
<div class="col-sm-8">
<select name="commonCurrency" class="form-control m-b" th:with="type=${@dict.getType('sys_common_currency')}">
<select name="commonCurrency" id="commonCurrency_add" class="form-control m-b" th:with="type=${@dict.getType('sys_common_currency')}" disabled>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" required></option>
</select>
</div>
@ -49,7 +49,7 @@
<label class="col-sm-4 control-label is-required">美元汇率:</label>
<div class="col-sm-8">
<div class="input-group">
<input name="usdRate" class="form-control" type="text" required>
<input name="usdRate" id="usdRate_add" class="form-control" type="text" required>
<span class="input-group-addon">%</span>
</div>
</div>
@ -65,7 +65,7 @@
<div class="container">
<h4 class="form-header h4">计算</h4>
<div class="col-xs-12 form-row">
<label class=" col-sm-2">物料合计:</label><input class="col-sm-4" name="materialSum" id="materialSum_add" type="text" readonly/>
<label class=" col-sm-2">物料合计:</label><input class="col-sm-4" name="materialSum" id="materialSum_add" type="number" readonly/>
<label class=" col-sm-2">数量合计:</label><input class="col-sm-4" name="enterpriseSum" id="enterpriseSum_add" type="number" readonly/>
</div>
<div class="col-xs-12 form-row">
@ -116,6 +116,9 @@
var materialTypeDatas = [[${@category.getChildByCode('materialType')}]];
var processMethodDatas = [[${@dict.getType('processMethod')}]];
var loginName = [[${@permission.getPrincipalProperty('loginName')}]];
var salesEstimateDetailVo = [[${salesEstimateDetailVo}]];
$("#form-estimate-add").validate({
focusCleanup: true
@ -130,11 +133,14 @@
}, {});
// 销售估价物料
var estimateMaterialTable = $('#bootstrap-table').bootstrapTable('getData');
if (estimateMaterialTable.length === 0){
$.modal.alertWarning("请至少添加一条物料信息");
return;
}
// 将表数据转换成与estimateData格式一致的数组
var estimateMaterialDataList = estimateMaterialTable.map(function(item) {
@ -163,6 +169,13 @@
};
});
// 获取料号档位的最新值
$('.form-control[id^="materialGearPosition_"]').each(function() {
const index = $(this).attr('id').match(/materialGearPosition_(\d+)/)[1]; // 提取索引
const value = $(this).val(); // 获取下拉框的值
estimateMaterialDataList[index].materialGearPosition = value; // 更新料号档位
});
const combinedData = Object.assign({}, estimateData, {
salesEstimateDetailList: estimateMaterialDataList,
});
@ -191,13 +204,23 @@
url: url,
callBack: estimateDoSubmit
};
$.modal.openOptions(options);
}
$(function() {
$("#businessMembers").val(loginName);
var options = {
id:'bootstrap-table',
showSearch: false,
showRefresh: false,
showToggle: false,
showColumns: false,
modalName: "销售估价详情",
columns: [{
editFiled:"noTaxRmb",
columns: [
{
checkbox: true
},
{
@ -245,9 +268,32 @@
},
{
title: '料号档位',
width: 100,
field: 'materialGearPosition',
formatter: function(value, row, index) {
return $.table.selectDictLabel(materialGearPositionDatas, value);
// 为每个下拉框添加唯一的 id 和 name
var selectId = 'materialGearPosition_' + index;
var selectName = 'salesEstimateDetailList[' + index + '].materialGearPosition';
// 创建下拉框 HTML
var html = $.common.sprintf(
"<select class='form-control' id='%s' name='%s' required>" +
" <option value='0' %s>A</option>" +
" <option value='1' %s>B</option>" +
" <option value='2' %s>C</option>" +
" <option value='3' %s>D</option>" +
" <option value='4' %s>E</option>" +
" <option value='5' %s>F</option>" +
"</select>",
selectId, selectName,
value === '0' ? 'selected' : '',
value === '1' ? 'selected' : '',
value === '2' ? 'selected' : '',
value === '3' ? 'selected' : '',
value === '4' ? 'selected' : '',
value === '5' ? 'selected' : ''
);
return html;
}
},
{
@ -300,7 +346,12 @@
actions.push('<a class="btn btn-danger btn-xs" href="javascript:void(0)" onclick="removeMaterialRow(\'' + row.materialNo + '\')"><i class="fa fa-remove"></i>删除</a> ');
return actions.join('');
}
}]
}],
onEditableSave:function(field, row, oldValue, $el){
// 确保getTotalAmount函数存在且正确引用
getTotalAmount();
},
};
$.table.init(options);
});
@ -316,7 +367,7 @@
for(var i=0;i<rows;i++){
var data = $("#bootstrap-table").bootstrapTable('getData')[i];
if(data.materialNo == rowData.materialCode){
if(data.materialNo == rowData.materialNo){
$.modal.alertError("不能选择已添加过的相同物料");
return;
}
@ -326,7 +377,7 @@
$("#bootstrap-table").bootstrapTable('insertRow', {
index:1,
row: {
materialNo:rowData.materialCode,
materialNo:rowData.materialNo,
materialPhotourl:rowData.photoUrl,
materialName: rowData.materialName,
materialType: rowData.materialType,
@ -335,8 +386,10 @@
materialUnit: rowData.unit,
materialProcessMethod: rowData.processMethod,
materialDeptType: rowData.warehouseDept,
materialNum: 0
}
})
getTotalAmount();
layer.close(index);
}
@ -346,6 +399,7 @@
field: 'materialNo',
values: materialNo
})
getTotalAmount();
}
@ -419,6 +473,122 @@
});
});
// $(document).ready(function() {
// // 监听表格中的物料数量输入框的变化
// $('#bootstrap-table').on('input', '.material-num-input', function() {
// getTotalAmount();
// });
//
// // 初始加载时也计算一次
// getTotalAmount();
// });
//
// function getTotalAmount() {
// let getData = $('#bootstrap-table').bootstrapTable('getData');
// let enterpriseSum = 0;
//
// // 计算物料数量总和
// enterpriseSum = getData.reduce((sum, item) => sum + (parseInt(item.materialNum) || 0), 0);
//
// // 更新页面上的输入框
// $("#enterpriseSum_add").val(enterpriseSum);
// }
//form计算模块
function getTotalAmount(){
let getData = $('#bootstrap-table').bootstrapTable('getData');
var materialSum = 0;
var enterpriseSum = 0;
var noTaxRmb = 0;
var taxRmb = 0;
var allNoTaxRmb = 0;
var allTaxRmb = 0;
var noTaxDollar = 0;
var taxDollar = 0;
var allNoTaxDollar = 0;
var allTaxDollar = 0;
materialSum = getData.length;
enterpriseSum = getData.reduce((sum, item) => sum + (parseInt(item.materialNum) || 0), 0);
for(var i=0;i<getData.length;i++){
noTaxRmb += parseFloat(getData[i].noTaxRmb) || 0;
taxRmb += parseFloat(getData[i].taxRmb) || 0;
allNoTaxRmb += parseFloat(getData[i].allNoTaxRmb) || 0;
allTaxRmb += parseFloat(getData[i].allTaxRmb) || 0;
noTaxDollar += parseFloat(getData[i].noTaxDollar) || 0;
taxDollar += parseFloat(getData[i].taxDollar) || 0;
allNoTaxDollar += parseFloat(getData[i].allNoTaxDollar) || 0;
allTaxDollar += parseFloat(getData[i].allTaxDollar) || 0;
}
noTaxRmb = noTaxRmb.toFixed(2);
taxRmb = taxRmb.toFixed(2);
allNoTaxRmb = allNoTaxRmb.toFixed(2);
allTaxRmb = allTaxRmb.toFixed(2);
noTaxDollar = noTaxDollar.toFixed(2);
taxDollar = taxDollar.toFixed(2);
allNoTaxDollar = allNoTaxDollar.toFixed(2);
allTaxDollar = allTaxDollar.toFixed(2);
$("input[name='materialSum']").val(materialSum);
$("input[name='enterpriseSum']").val(enterpriseSum);
$("input[name='noTaxRmb']").val(noTaxRmb);
$("input[name='taxRmb']").val(taxRmb);
$("input[name='allNoTaxRmb']").val(allNoTaxRmb);
$("input[name='allTaxRmb']").val(allTaxRmb);
$("input[name='noTaxDollar']").val(noTaxDollar);
$("input[name='taxDollar']").val(taxDollar);
$("input[name='allNoTaxDollar']").val(allNoTaxDollar);
$("input[name='allTaxDollar']").val(allTaxDollar);
}
// 计算并更新所有其他总和
// function updateAllSums() {
// let getData = $('#bootstrap-table').bootstrapTable('getData');
// let noTaxRmb = 0;
// let taxRmb = 0;
// let allNoTaxRmb = 0;
// let allTaxRmb = 0;
// let noTaxDollar = 0;
// let taxDollar = 0;
// let allNoTaxDollar = 0;
// let allTaxDollar = 0;
//
// getData.forEach(item => {
// noTaxRmb += parseFloat(item.noTaxRmb) || 0;
// taxRmb += parseFloat(item.taxRmb) || 0;
// allNoTaxRmb += parseFloat(item.allNoTaxRmb) || 0;
// allTaxRmb += parseFloat(item.allTaxRmb) || 0;
// noTaxDollar += parseFloat(item.noTaxDollar) || 0;
// taxDollar += parseFloat(item.taxDollar) || 0;
// allNoTaxDollar += parseFloat(item.allNoTaxDollar) || 0;
// allTaxDollar += parseFloat(item.allTaxDollar) || 0;
// });
//
// noTaxRmb = noTaxRmb.toFixed(2);
// taxRmb = taxRmb.toFixed(2);
// allNoTaxRmb = allNoTaxRmb.toFixed(2);
// allTaxRmb = allTaxRmb.toFixed(2);
// noTaxDollar = noTaxDollar.toFixed(2);
// taxDollar = taxDollar.toFixed(2);
// allNoTaxDollar = allNoTaxDollar.toFixed(2);
// allTaxDollar = allTaxDollar.toFixed(2);
//
// $("input[name='noTaxRmb']").val(noTaxRmb);
// $("input[name='taxRmb']").val(taxRmb);
// $("input[name='allNoTaxRmb']").val(allNoTaxRmb);
// $("input[name='allTaxRmb']").val(allTaxRmb);
// $("input[name='noTaxDollar']").val(noTaxDollar);
// $("input[name='taxDollar']").val(taxDollar);
// $("input[name='allNoTaxDollar']").val(allNoTaxDollar);
// $("input[name='allTaxDollar']").val(allTaxDollar);
// }
</script>
</body>
</html>
Loading…
Cancel
Save