优化销售订单审核功能

This commit is contained in:
Mrking 2024-10-20 22:30:21 +08:00
parent 6858a908c3
commit 6ff368298d
8 changed files with 185 additions and 37 deletions

View File

@ -13,6 +13,7 @@ public interface ErrorCodeConstants extends cn.hangtag.module.system.enums.Erro
ErrorCode SHAPE_TEMPLATE_NOT_EXISTS = new ErrorCode(3400, "图形模板管理 不存在");
ErrorCode DRAFT_DESIGN_DATA_NOT_EXISTS = new ErrorCode(3500, "稿件模板数据 不存在");
ErrorCode SALE_ORDER_NOT_EXISTS = new ErrorCode(3600, "OMS销售订单不存在");
ErrorCode SALE_ORDER_NOT_DELETE = new ErrorCode(3601, "OMS销售订单已审核不允许删除");
ErrorCode SALE_ORDER_ENTRY_NOT_EXISTS = new ErrorCode(3700, "OMS销售订单明细不存在");
ErrorCode SALE_ORDER_ENTRY_PRICE_NOT_NULL= new ErrorCode(3701, "单价不允许为空");
ErrorCode SALE_ORDER_SKU_NOT_EXISTS = new ErrorCode(3702, "产品单价记录不存在");

View File

@ -27,7 +27,7 @@ public class SaleOrderEntryItemDTO implements Serializable {
/**
* 产品id
*/
private Integer productId;
private Long productId;
/**
* 产品编码

View File

@ -72,9 +72,7 @@ public interface SaleOrderService {
Map<Integer, Long> getTabsCount(Long customerId);
default void updateSaleOrderBillStatus(List<Long> ids, String status){
updateSaleOrderBillStatus(ids,status,null);
}
void updateSaleOrderBillStatus(List<Long> ids, String status);
void updateSaleOrderBillStatus(List<Long> ids, String status,Map<String,Object> params);
void generateProduceOrder(List<Long> ids);
@ -110,4 +108,5 @@ public interface SaleOrderService {
Long placeOrder(CreateSaleOrderDTO dto);
public String getNewOrderCode();
public String getNewOrderCode2();
}

View File

@ -14,6 +14,7 @@ import cn.hangtag.module.oms.common.utils.WKHtmlToPdfUtil;
import cn.hangtag.module.oms.controller.admin.common.vo.DataComparisonRespVO;
import cn.hangtag.module.oms.controller.admin.produceorder.vo.ProduceOrderSaveReqVO;
import cn.hangtag.module.oms.controller.admin.product.vo.ProductPriceSaveReqVO;
import cn.hangtag.module.oms.controller.admin.salecontract.vo.SaleContractSaveReqVO;
import cn.hangtag.module.oms.controller.admin.saleorder.front.dto.CreateSaleOrderDTO;
import cn.hangtag.module.oms.controller.admin.saleorder.front.dto.SaleOrderEntryItemDTO;
import cn.hangtag.module.oms.controller.admin.saleorder.front.dto.SaleOrderSkuDTO;
@ -25,6 +26,7 @@ import cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderTrendReqVO;
import cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderTrendRespVO;
import cn.hangtag.module.oms.convert.saleorder.SaleOrderConvert;
import cn.hangtag.module.oms.dal.dataobject.customer.CustomerDO;
import cn.hangtag.module.oms.dal.dataobject.produceorder.ProduceOrderDO;
import cn.hangtag.module.oms.dal.dataobject.product.ProductPriceDO;
import cn.hangtag.module.oms.dal.dataobject.productinfo.ProductInfoDO;
import cn.hangtag.module.oms.dal.dataobject.salecontract.SaleContractDO;
@ -33,6 +35,7 @@ import cn.hangtag.module.oms.dal.dataobject.saleorder.SaleOrderDO;
import cn.hangtag.module.oms.dal.dataobject.saleorderentry.SaleOrderEntryDO;
import cn.hangtag.module.oms.dal.dataobject.saleordersku.SaleOrderSkuDO;
import cn.hangtag.module.oms.dal.mysql.customer.CustomerMapper;
import cn.hangtag.module.oms.dal.mysql.salecontract.SaleContractMapper;
import cn.hangtag.module.oms.dal.mysql.saleorder.SaleOrderMapper;
import cn.hangtag.module.oms.dal.mysql.saleorderentry.SaleOrderEntryMapper;
import cn.hangtag.module.oms.dal.mysql.saleordersku.SaleOrderSkuMapper;
@ -47,11 +50,15 @@ import cn.hangtag.module.oms.service.produceorder.ProduceOrderService;
import cn.hangtag.module.oms.service.product.ProductPriceService;
import cn.hangtag.module.oms.service.productinfo.ProductInfoService;
import cn.hangtag.module.oms.service.salecontract.SaleContractService;
import cn.hangtag.module.system.mq.message.mail.MailSendMessage;
import cn.hangtag.module.system.service.mail.MailAccountService;
import cn.hangtag.module.system.service.mail.MailSendService;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
@ -82,6 +89,7 @@ import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static cn.hangtag.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.hangtag.module.oms.enums.ErrorCodeConstants.SALE_ORDER_NOT_DELETE;
import static cn.hangtag.module.oms.enums.ErrorCodeConstants.SALE_ORDER_NOT_EXISTS;
/**
@ -96,16 +104,19 @@ import static cn.hangtag.module.oms.enums.ErrorCodeConstants.SALE_ORDER_NOT_EXIS
public class SaleOrderServiceImpl implements SaleOrderService {
private final SaleOrderMapper saleOrderMapper;
private final SaleOrderEntryMapper saleOrderEntryMapper;
private final SaleOrderSkuMapper skuOrderSkuMapper;
private final ProduceOrderService produceOrderService;
private final ProductInfoService productInfoService;
private final SaleContractService saleContractService;
private final CustomerService customerService;
private final CustomerMapper customerMapper;
private final ProductPriceService productPriceService;
private final TemplateEngine templateEngine;
private SaleOrderMapper saleOrderMapper;
private SaleContractMapper saleContractMapper;
private SaleOrderEntryMapper saleOrderEntryMapper;
private SaleOrderSkuMapper skuOrderSkuMapper;
private ProduceOrderService produceOrderService;
private ProductInfoService productInfoService;
private SaleContractService saleContractService;
private CustomerService customerService;
private CustomerMapper customerMapper;
private ProductPriceService productPriceService;
private TemplateEngine templateEngine;
private MailSendService mailSendService;
private MailAccountService mailAccountService;
@Override
@ -129,7 +140,6 @@ public class SaleOrderServiceImpl implements SaleOrderService {
// 更新
SaleOrderDO updateObj = BeanUtils.toBean(updateReqVO, SaleOrderDO.class);
saleOrderMapper.updateById(updateObj);
// 更新子表
updateSaleOrderEntryList(updateReqVO.getId(), updateReqVO.getEntrys());
}
@ -138,6 +148,7 @@ public class SaleOrderServiceImpl implements SaleOrderService {
@Transactional(rollbackFor = Exception.class)
public void deleteSaleOrder(Long id) {
// 校验存在
validateSaleOrderStatus(id);
validateSaleOrderExists(id);
// 删除
saleOrderMapper.deleteById(id);
@ -152,6 +163,15 @@ public class SaleOrderServiceImpl implements SaleOrderService {
}
}
private void validateSaleOrderStatus(Long id) {
SaleOrderDO saleOrderDO = saleOrderMapper.selectById(id);
if (saleOrderDO == null) {
if(BillStatusEnum.AUDIT.getValue().equals(saleOrderDO.getBillStatus())){
throw exception(SALE_ORDER_NOT_DELETE);
}
}
}
@Override
public SaleOrderDO getSaleOrder(Long id) {
return saleOrderMapper.selectById(id);
@ -212,9 +232,14 @@ public class SaleOrderServiceImpl implements SaleOrderService {
saleOrderMapper.selectCount(lambdaQueryWrapper2));
return counts;
}
@Override
public void updateSaleOrderBillStatus(List<Long> ids, String status,Map<String,Object> params) {
@Transactional(rollbackFor = Exception.class)
public void updateSaleOrderBillStatus(List<Long> ids, String status){
updateSaleOrderBillStatus(ids,status);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateSaleOrderBillStatus(List<Long> ids, String status,Map<String,Object> params){
List<SaleOrderDO> saleOrders = saleOrderMapper.selectList(SaleOrderDO::getId, ids);
switch (status){
case "invalid":
@ -253,7 +278,7 @@ public class SaleOrderServiceImpl implements SaleOrderService {
if(entrys==null||entrys.isEmpty()){
throw new ServiceException(001,"产品明细为空");
}
for (cn.hangtag.module.oms.dal.dataobject.saleorderentry.SaleOrderEntryDO entry : entrys) {
for (SaleOrderEntryDO entry : entrys) {
BigDecimal price = entry.getPrice();
if(price==null){
throw new ServiceException(ErrorCodeConstants.SALE_ORDER_ENTRY_PRICE_NOT_NULL);
@ -269,15 +294,37 @@ public class SaleOrderServiceImpl implements SaleOrderService {
//生成产品单价记录
for (cn.hangtag.module.oms.dal.dataobject.saleorderentry.SaleOrderEntryDO entry : entrys) {
for (SaleOrderEntryDO entry : entrys) {
Long parentId = entry.getParentId();
BigDecimal price = entry.getPrice();
generateProductPrice(parentId,price);
}
//生成销售合约
Long saleContractId = generateSaleContract(saleOrder,entrys);
String htmlContent = generateHtmlContent(saleContractId);
String fileName = StrUtil.format("C:\\Users\\Admin\\Desktop\\1111111\\test\\test_{}",
new Date().getTime());
String templatePath = fileName + ".html";
String pdfPath = fileName + ".pdf";
FileUtil.writeString(htmlContent,templatePath, "UTF-8");
WKHtmlToPdfUtil.convert(templatePath, pdfPath);
//发送消息
MailSendMessage message = new MailSendMessage();
message.setAccountId(1L);
message.setMail("wx782276617@foxmail.com");
message.setTitle("OMS订单系统");
message.setContent("您好,您的订单:"+saleOrder.getBillno()+",已审核通过!");
mailSendService.doSendMail(message,new File(fileName));
//mailSendService.doSendMail(message);
}
}
break;
}
}
@ -352,7 +399,7 @@ public class SaleOrderServiceImpl implements SaleOrderService {
context.setVariable("price"+j, saleContractEntryDO.getPrice());
context.setVariable("discount"+j, saleContractEntryDO.getDiscount());
context.setVariable("amount"+j, saleContractEntryDO.getAmount());
context.setVariable("deliverydate"+j, saleContractEntryDO.getDeliveryDate());
context.setVariable("deliverydate"+j, DateUtil.date(saleContractEntryDO.getDeliveryDate()).toDateStr());
context.setVariable("explain"+j+"1", name);
context.setVariable("explain"+j+"2", details);
context.setVariable("explain"+j+"3", "");
@ -499,6 +546,7 @@ public class SaleOrderServiceImpl implements SaleOrderService {
return order.getId();
}
private static final long codeId = 6L;
private static final long saleContractCodeId = 7L;
@Override
public String getNewOrderCode() {
String s = "";
@ -518,6 +566,25 @@ public class SaleOrderServiceImpl implements SaleOrderService {
}
}
}
@Override
public String getNewOrderCode2() {
String s = "";
int count = 10;
while (true){
count --;
try {
s = CodingRulesUtils.generateCode(saleContractCodeId, false);
checkCode2(null,s);
return s;
}catch (ServiceException e){
log.warn("重复或者下一个编码");
if(count < 0){
log.error("编码获取失败");
return "";
}
}
}
}
private void checkCode(Long id,String code){
if(FuncUtil.isNotEmpty(code)){
LambdaQueryWrapper<SaleOrderDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
@ -538,6 +605,28 @@ public class SaleOrderServiceImpl implements SaleOrderService {
}
}
}
private void checkCode2(Long id,String code){
if(FuncUtil.isNotEmpty(code)){
LambdaQueryWrapper<SaleContractDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.select(SaleContractDO::getId,SaleContractDO::getBillno, BaseDO::getDeleted);
lambdaQueryWrapper.eq(SaleContractDO::getBillno, code);
lambdaQueryWrapper.eq(SaleContractDO::getDeleted,false);
List<SaleContractDO> dos = saleContractMapper.selectList(lambdaQueryWrapper);
if(FuncUtil.isEmpty(id) && FuncUtil.isNotEmpty(dos)){
throw exception(GlobalErrorCodeConstants.DATA_DUPLICATE);
}
if (FuncUtil.isNotEmpty(id) && FuncUtil.isNotEmpty(dos)) {
for (SaleContractDO aDo : dos) {
// 出现重复并当前id 不一致
if(!FuncUtil.equals(aDo.getId(), id)){
throw exception(GlobalErrorCodeConstants.DATA_DUPLICATE);
}
}
}
}
}
private SaleOrderDO wrapperEntity(SaleOrderDO order,CreateSaleOrderDTO dto){
// 客户信息
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
@ -553,7 +642,7 @@ public class SaleOrderServiceImpl implements SaleOrderService {
order.setPlansenddate( FuncUtil.parseDate(dto.getPlansenddate()));
// 设置订单状态
order.setOrderStatus(SaleOrderStatusEnum.YXD.getValue());
order.setBillStatus(BillStatusEnum.SAVE.getValue());
order.setBillStatus(BillStatusEnum.SUBMIT.getValue());
String orderType = order.getOrderType();
if(FuncUtil.isEmpty(orderType)){
order.setOrderType(SaleOrderTypeEnum.NORMAL.getType());
@ -590,8 +679,27 @@ public class SaleOrderServiceImpl implements SaleOrderService {
}
private void createSaleOrderEntryList(Long parentId, List<SaleOrderEntryDO> list) {
BigDecimal amount = BigDecimal.ZERO;
list.forEach(o -> o.setParentId(parentId));
for (SaleOrderEntryDO saleOrderEntryDO : list) {
BigDecimal price = saleOrderEntryDO.getPrice();
Integer qty = saleOrderEntryDO.getQty();
BigDecimal discount = saleOrderEntryDO.getDiscount();
if(price!=null){
if(discount!=null){
saleOrderEntryDO.setAmount(price.multiply(BigDecimal.valueOf(qty)).multiply(discount));
}else {
saleOrderEntryDO.setAmount(price.multiply(BigDecimal.valueOf(qty)));
}
amount = amount.add(saleOrderEntryDO.getAmount());
}
}
saleOrderEntryMapper.insertBatch(list);
//更新总金额
/*SaleOrderDO saleOrderDO = new SaleOrderDO();
saleOrderDO.setId(parentId);
saleOrderDO.setOrderAmount(amount);
saleOrderMapper.updateById(saleOrderDO);*/
}
private void updateSaleOrderEntryList(Long parentId, List<SaleOrderEntryDO> list) {
@ -624,4 +732,41 @@ public class SaleOrderServiceImpl implements SaleOrderService {
}
}
private Long generateSaleContract(SaleOrderDO saleOrder, List<SaleOrderEntryDO> entrys){
CustomerDO customer = customerService.getCustomer(saleOrder.getCustomerId());
SaleContractSaveReqVO saveReqVO = new SaleContractSaveReqVO();
saveReqVO.setBillno(getNewOrderCode2());
saveReqVO.setCustomerId(saleOrder.getCustomerId());
saveReqVO.setCustomerName(customer.getName());
saveReqVO.setCustomerBuyNo(saleOrder.getBillno());
saveReqVO.setBizdate(saleOrder.getBizdate());
saveReqVO.setPartyA("XXXXXXXXXXXXXXXXX");
saveReqVO.setPartyB(customer.getCompany());
saveReqVO.setHead(customer.getGdperson());
saveReqVO.setClerk(customer.getSaleperson());
saveReqVO.setPhone(customer.getPhone());
saveReqVO.setFax(null);
saveReqVO.setAmount(saleOrder.getOrderAmount());
saveReqVO.setAddress(saleOrder.getDeliveryAddress());
List<SaleContractEntryDO> list = new ArrayList<>();
for (SaleOrderEntryDO entry : entrys) {
ProductInfoDO productInfo = productInfoService.getProductInfo(entry.getMaterialId());
SaleContractEntryDO saleContractEntryDO = new SaleContractEntryDO();
saleContractEntryDO.setProductId(entry.getMaterialId());
saleContractEntryDO.setProductNumber(productInfo.getCode());
saleContractEntryDO.setProductName(productInfo.getName());
saleContractEntryDO.setPrice(entry.getPrice());
saleContractEntryDO.setQty(entry.getQty());
saleContractEntryDO.setDiscount(entry.getDiscount());
saleContractEntryDO.setDeliveryDate(entry.getDeliveryDate());
saleContractEntryDO.setAmount(entry.getAmount());
list.add(saleContractEntryDO);
}
saveReqVO.setSaleContractEntrys(list);
return saleContractService.createSaleContract(saveReqVO);
}
}

View File

@ -2,6 +2,7 @@ package cn.hangtag.module.system.service.mail;
import cn.hangtag.module.system.mq.message.mail.MailSendMessage;
import java.io.File;
import java.util.Map;
/**
@ -55,6 +56,9 @@ public interface MailSendService {
*
* @param message 邮件
*/
void doSendMail(MailSendMessage message);
default void doSendMail(MailSendMessage message){
doSendMail(message, null);
}
void doSendMail(MailSendMessage message, File... files);
}

View File

@ -18,6 +18,7 @@ import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.io.File;
import java.util.Map;
import static cn.hangtag.framework.common.exception.util.ServiceExceptionUtil.exception;
@ -101,14 +102,14 @@ public class MailSendServiceImpl implements MailSendService {
}
@Override
public void doSendMail(MailSendMessage message) {
public void doSendMail(MailSendMessage message, File... files) {
// 1. 创建发送账号
MailAccountDO account = validateMailAccount(message.getAccountId());
MailAccount mailAccount = buildMailAccount(account, message.getNickname());
// 2. 发送邮件
try {
String messageId = MailUtil.send(mailAccount, message.getMail(),
message.getTitle(), message.getContent(), true);
message.getTitle(), message.getContent(), true,files);
// 3. 更新结果成功
mailLogService.updateMailSendResult(message.getLogId(), messageId, null);
} catch (Exception e) {

View File

@ -201,11 +201,6 @@ const updateAddress = () => {
updateAddressFormRef.value?.open(formData.value)
}
const changeRow = async (row,key:string) => {
if('price' == key || 'discount' == key ){
let price = row.price
@ -234,6 +229,8 @@ const handleAudit = async () => {
await itemFormEntrysRef.value.validate()
//
await message.confirm('确认审核订单吗?')
//
await SaleOrderApi.updateOrderEntrys(formData.value)
//
await SaleOrderApi.updateSaleOrderBillStatus([formData.value.id],'audit')
message.success('审核成功')

View File

@ -130,13 +130,13 @@
>
作废
</el-button>
<el-button
<!-- <el-button
type="warning"
plain
@click="handleUpdateBillStatus('submit')"
:disabled="selectionList.length === 0"
>提交
</el-button>
</el-button>-->
<el-button
type="primary"
plain
@ -182,7 +182,7 @@
:row-class-name="tableRowClassName"
>
<el-table-column width="30" label="选择" type="selection" />
<el-table-column label="单据编号" align="center" prop="billno" width="120px"/>
<el-table-column label="单据编号" align="center" prop="billno" width="220px"/>
<el-table-column label="客户" align="center" prop="customerId" width="120px"/>
<el-table-column label="销售员" align="center" prop="customerId" width="180px"/>
<el-table-column label="跟单员" align="center" prop="customerId" width="180px"/>
@ -307,17 +307,17 @@ const total = ref(0) // 列表的总页数
// tabs
const tabsData = ref([
{
name: '已下单',
name: '待审核',
type: 0,
count: 0
},
{
name: '生产中',
name: '待排产',
type: 1,
count: 0
},
{
name: '已完成',
name: '已排产',
type: 2,
count: 0
}
@ -358,6 +358,7 @@ const getList = async () => {
} finally {
loading.value = false
}
getTabsCount()
}
@ -574,8 +575,8 @@ onActivated(() => {
/** 初始化 **/
onMounted(() => {
getList()
//
getTabsCount()
//
//getTabsCount()
})
</script>