更新0815

This commit is contained in:
xyc 2025-08-15 13:06:16 +08:00
parent 15e54c5984
commit d85b0d8028
5 changed files with 310 additions and 195 deletions

View File

@ -31,6 +31,7 @@ import cn.iocoder.yudao.module.tickets.service.DlRepairTicketsService;
import cn.iocoder.yudao.module.tickets.service.DlRepairTitemService;
import cn.iocoder.yudao.module.tickets.service.DlTicketWaresService;
import cn.iocoder.yudao.module.tickets.service.DlTwItemService;
import cn.iocoder.yudao.module.tickets.utils.TicketsOperateUtil;
import cn.iocoder.yudao.module.tickets.vo.AppWaresGroupVO;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@ -44,6 +45,7 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@ -53,7 +55,6 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
/**
* 针对表dl_repair_so(采购单领料单)的数据库操作Service实现
*
* @author 小李
* @date 9:11 2024/9/13
**/
@ -108,9 +109,11 @@ public class DlRepairSoServiceImpl extends ServiceImpl<DlRepairSoMapper, DlRepai
@Lazy
private RepairRecordsService recordsService;
@Resource
private TicketsOperateUtil operateUtil;
/**
* 采购单/领料单 新增
*
* @param repairSoRespVO 采购单对象
* @author 小李
* @date 10:49 2024/9/14
@ -171,7 +174,6 @@ public class DlRepairSoServiceImpl extends ServiceImpl<DlRepairSoMapper, DlRepai
/**
* 采购单/领料单新增分页
*
* @param repairSoReqVO 查询对象
* @author 小李
* @date 18:14 2024/9/14
@ -183,7 +185,6 @@ public class DlRepairSoServiceImpl extends ServiceImpl<DlRepairSoMapper, DlRepai
/**
* 采购单/领料单 作废
*
* @param repairSoReqVO 作废对象
* @author 小李
* @date 11:12 2024/9/18
@ -272,7 +273,6 @@ public class DlRepairSoServiceImpl extends ServiceImpl<DlRepairSoMapper, DlRepai
/**
* 采购单/领料单 查看
*
* @param id 主键
* @author 小李
* @date 9:34 2024/9/22
@ -306,7 +306,6 @@ public class DlRepairSoServiceImpl extends ServiceImpl<DlRepairSoMapper, DlRepai
/**
* 员工确认领料
*
* @param id 单据ID 领料单主表
* @author 小李
* @date 11:58 2024/10/21
@ -376,7 +375,6 @@ public class DlRepairSoServiceImpl extends ServiceImpl<DlRepairSoMapper, DlRepai
/**
* 员工确认退料
*
* @param id 退料单主表ID
* @author 小李
* @date 19:41 2024/10/21
@ -441,12 +439,12 @@ public class DlRepairSoServiceImpl extends ServiceImpl<DlRepairSoMapper, DlRepai
/**
* 领料退料计算工单子表的通用方法
* @author vinjor-M
* @date 14:31 2024/12/4
* @param ifGet 是否是领料
* @param applyId 配件申请单id
* @param sois 领料单退料单配件明细
* @param repairWares 配件库的明细
* @author vinjor-M
* @date 14:31 2024/12/4
**/
private void dealWareItem(Boolean ifGet, String applyId, List<DlRepairSoi> sois, List<RepairWares> repairWares) {
//配件申请单
@ -475,6 +473,20 @@ public class DlRepairSoServiceImpl extends ServiceImpl<DlRepairSoMapper, DlRepai
item.setItemCount(item.getItemCount() + repairSoi.getGoodsCount());
item.setItemMoney(item.getItemPrice().multiply(BigDecimal.valueOf(item.getItemCount())).multiply(item.getItemDiscount()));
item.setItemStatus(TicketsItemStatusEnum.RECEIVED.getCode());
// 获取配件的售价和进价
BigDecimal salePrice = repairWaresMap.get(repairSoi.getGoodsId()).getPrice(); // 售价
BigDecimal purchasePrice = repairWaresMap.get(repairSoi.getGoodsId()).getPurPrice(); // 进价
//计算利润
BigDecimal profit = operateUtil.calcProfit(salePrice, purchasePrice, item.getItemCount());
// 计算毛利率
BigDecimal profitRate = operateUtil.calcProfitRate(salePrice, purchasePrice, item.getItemCount());
item.setItemProfit(profit);
item.setItemProfitRate(profitRate);
saveOrUpdateList.add(item);
} else {
//退料
@ -485,6 +497,19 @@ public class DlRepairSoServiceImpl extends ServiceImpl<DlRepairSoMapper, DlRepai
item.setItemCount(item.getItemCount() - repairSoi.getGoodsCount());
item.setItemMoney(item.getItemPrice().multiply(BigDecimal.valueOf(item.getItemCount())).multiply(item.getItemDiscount()));
item.setItemStatus(TicketsItemStatusEnum.RECEIVED.getCode());
// 重新计算利润和利润率
BigDecimal salePrice = repairWaresMap.get(repairSoi.getGoodsId()).getPrice(); // 售价
BigDecimal purchasePrice = repairWaresMap.get(repairSoi.getGoodsId()).getPurPrice(); // 进价
//计算利润
BigDecimal profit = operateUtil.calcProfit(salePrice, purchasePrice, item.getItemCount());
// 计算毛利率
BigDecimal profitRate = operateUtil.calcProfitRate(salePrice, purchasePrice, item.getItemCount());
item.setItemProfit(profit);
item.setItemProfitRate(profitRate);
saveOrUpdateList.add(item);
} else {
//现有数量小于或等于要退的数量直接将这个配件删掉
@ -515,6 +540,18 @@ public class DlRepairSoServiceImpl extends ServiceImpl<DlRepairSoMapper, DlRepai
titem.setSaleName(dlTicketWares.getAdviserName());
titem.setPartId(repairSoi.getGoodsId());
titem.setItemStatus(TicketsItemStatusEnum.RECEIVED.getCode());
// 获取售价和进价
BigDecimal salePrice = waresItem.getPrice(); // 售价
BigDecimal purchasePrice = waresItem.getPurPrice(); // 进价
//计算利润
BigDecimal profit = operateUtil.calcProfit(salePrice, purchasePrice, titem.getItemCount());
// 计算毛利率
BigDecimal profitRate = operateUtil.calcProfitRate(salePrice, purchasePrice, titem.getItemCount());
titem.setItemProfitRate(profitRate);
titem.setItemProfit(profit);
saveOrUpdateList.add(titem);
} else {
//退料不可能出现没领料就退料的情况不用处理
@ -531,9 +568,9 @@ public class DlRepairSoServiceImpl extends ServiceImpl<DlRepairSoMapper, DlRepai
ticketsService.computeTicket(dlTicketWares.getTicketId());
}
/**
* 采购入库
*
* @param reqVO 接参实体中需传入采购单id单据编号soNo备注remark,入库总价totalPrice子表中商品id子表中入库数量inCount
* @author PQZ
* @date 14:32 2024/10/24
@ -649,7 +686,6 @@ public class DlRepairSoServiceImpl extends ServiceImpl<DlRepairSoMapper, DlRepai
/**
* 领料单退料单APP查看
*
* @param id 单据id
* @return cn.iocoder.yudao.framework.common.pojo.CommonResult<?>
* @author vinjor-M

View File

@ -61,6 +61,16 @@ public class DlRepairTitem extends TenantBaseDO {
*/
private BigDecimal itemMoney;
/**
* 利润
*/
private BigDecimal itemProfit;
/**
* 毛利率
*/
private BigDecimal itemProfitRate;
/**
* 维修人员ID(system_users表的ID)
*/

View File

@ -86,6 +86,7 @@ import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
@ -100,7 +101,6 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
/**
* 针对表dl_repair_tickets(维修工单表)的数据库操作Service实现
*
* @author 小李
* @date 18:19 2024/9/13
**/
@ -202,7 +202,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 维修工单表 新增
*
* @param ticketsRespVO 新增对象
* @author 小李
* @date 11:33 2024/9/20
@ -382,7 +381,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 维修工单表 分页
*
* @param repairTicketsReqVO 查询对象
* @author 小李
* @date 20:51 2024/9/20
@ -394,7 +392,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 获得一个工单的详细信息
*
* @param id 工单ID
* @param ifApp 是否是APP发起的查询
* @author 小李
@ -570,13 +567,45 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
List<DictDataRespDTO> recordTypeList = dictDataApi.getDictDataList(DICT_REPAIR_RECORDS_TYPE);
Map<String, String> typeMap = recordTypeList.stream().collect(Collectors.toMap(DictDataRespDTO::getValue, DictDataRespDTO::getLabel));
result.setRecords(records.stream().peek(item -> item.setType(typeMap.get(item.getType()))).collect(Collectors.toList()));
//配件总利润
BigDecimal waresProfit = BigDecimal.ZERO;
if (CollectionUtil.isNotEmpty(items)) {
for (DlRepairTitemReqVO item : items) {
if ("02".equals(item.getItemType())) {
// 获取配件利润 加到总利润中
BigDecimal itemProfit = item.getItemProfit() != null ? item.getItemProfit() : BigDecimal.ZERO;
waresProfit = waresProfit.add(itemProfit);
System.out.println("配件利润:" + itemProfit);
}
}
}
//计算含工时项目毛利率
//配件总利润除以工单总价
BigDecimal profitRate = new BigDecimal(0);
if (ObjectUtil.isNotEmpty(dlRepairTickets.getTotalPrice())) {
if (dlRepairTickets.getTotalPrice().compareTo(BigDecimal.ZERO) != 0) {
profitRate = waresProfit.divide(dlRepairTickets.getTotalPrice(), 2, RoundingMode.HALF_UP);
}
result.setProfitRate(profitRate);
}
//计算不含工时项目毛利率
if (ObjectUtil.isNotEmpty(dlRepairTickets.getPartPrice())) {
BigDecimal profitRateNo = new BigDecimal(0);
if (dlRepairTickets.getPartPrice().compareTo(BigDecimal.ZERO) != 0) {
profitRateNo = waresProfit.divide(dlRepairTickets.getPartPrice(), 2, RoundingMode.HALF_UP);
}
result.setProfitRateNo(profitRateNo);
}
return result;
}
/**
* 维修工单表 作废
* 传对象是因为需要有作废备注
*
* @param repairTicketsReqVO 工单对象
* @author 小李
* @date 19:46 2024/9/22
@ -600,7 +629,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 维修工单表 结算
*
* @param repairTicketsRespVO 工单
* @author 小李
* @date 8:50 2024/9/23
@ -648,7 +676,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 客户信息和车辆信息 新增修改
*
* @param customerAndCarVO 用户信息和车辆信息
* @author 小李
* @date 9:25 2024/10/8
@ -734,7 +761,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 打印工单
*
* @param response HttpServletResponse
* @param id String
* @author PQZ
@ -1032,10 +1058,10 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 翻译字典
* @author vinjor-M
* @date 16:25 2025/1/9
* @param dlRepairTicketsIPage TODO
* @return com.baomidou.mybatisplus.core.metadata.IPage<cn.iocoder.yudao.module.tickets.entity.DlRepairTickets>
* @author vinjor-M
* @date 16:25 2025/1/9
**/
private IPage<DlRepairTickets> dealDictText(IPage<DlRepairTickets> dlRepairTicketsIPage) {
//维修类型
@ -1065,7 +1091,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 分类查询工单分页
*
* @param repairTicketsReqVO 查询对象
* @author 小李
* @date 16:26 2024/10/12
@ -1184,7 +1209,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 判断登录用户的角色针对维修工单中的四个角色
*
* @author 小李
* @date 9:28 2024/10/14
**/
@ -1229,7 +1253,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 接单
*
* @param id 工单ID
* @author 小李
* @date 11:48 2024/10/14
@ -1265,7 +1288,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 指派员工通知施工
*
* @param reqVO 请求对象
* @author 小李
* @date 15:34 2024/10/14
@ -1312,7 +1334,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 指派施工施工项目中不包含选中人员处理
*
* @param ticketId 工单id
* @param nowRepairId 当前处理人id
* @param nowRepairName 当前处理人名称
@ -1361,7 +1382,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 更新工单状态(针对开始施工施工中记录施工完成)
*
* @param respVO 请求对象
* @author 小李
* @date 15:46 2024/10/18
@ -1509,7 +1529,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 配件客户是否可见
*
* @param id 工单ID
* @param show 是否可见 1可见 0不可见
* @author 小李
@ -1528,7 +1547,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 查待总检或待出厂检验的工单
* 维修服务顾问和总检用的
*
* @param repairTicketsReqVO 请求对象
* @author 小李
* @date 11:40 2024/10/23
@ -1563,7 +1581,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 维修总检完成总检
*
* @param respVO 请求对象
* @author 小李
* @date 16:48 2024/10/23
@ -1603,7 +1620,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 用于同步一个工单的所有配件申请表的数据到维修工单主要针对已领取数量小于申请数量的情况
*
* @param id 维修工单ID
* @author 小李
* @date 9:52 2024/10/26
@ -1674,7 +1690,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 服务顾问上传出厂检验日志
*
* @param respVO 请求对象
* @author 小李
* @date 17:47 2024/10/23
@ -1697,7 +1712,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 从总检的角度差维修中已完成的工单数量
*
* @return java.util.Map<java.lang.String, java.lang.Integer>
* @author vinjor-M
* @date 11:30 2024/10/24
@ -1789,7 +1803,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 服务顾问通知客户取车
*
* @param noticeCusVO 请求对象
* @author 小李
* @date 22:40 2024/10/23
@ -1843,7 +1856,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 判断是否工单子表的任何一个类目没有价格或价格为0
*
* @param id 工单ID
* @author 小李
* @date 15:00 2024/11/16
@ -1866,7 +1878,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 重新计算工单的一些数值子表也要重新计算
*
* @param ticketId 工单ID
* @author 小李
* @date 15:47 2024/10/24
@ -1955,7 +1966,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 新增工单子项
*
* @param respVO 主要有两个参数主表ID,itemList(这个需要前端处理成子表的对象能接收的数据)
* @author 小李
* @date 19:59 2024/10/24
@ -1986,7 +1996,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 超时自动总检
*
* @author 小李
* @date 16:35 2024/10/26
**/
@ -2069,7 +2078,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 修改工单主表只是主表
*
* @param respVO 请求对象
* @author 小李
* @date 10:25 2024/10/30
@ -2089,7 +2097,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 删除工单
*
* @param id 工单ID
* @author 小李
* @date 20:05 2024/11/1
@ -2109,8 +2116,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 服务顾问交车
*
* @param respVO
* @author vinjor-M
* @date 16:51 2024/11/13
**/
@ -2136,10 +2141,9 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 根据工单ID查客户和车辆信息
*
* @param id id
* @author 小李
* @date 19:07 2024/11/18
* @param id id
**/
@Override
public CustomerAndCarVO getCusAndCarById(String id) {
@ -2158,10 +2162,9 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
/**
* 用于刷新工单的更新时间
*
* @param id 工单ID
* @author 小李
* @date 10:31 2024/11/27
* @param id 工单ID
**/
@Override
public void refreshUpdateTime(String id) {

View File

@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.tickets.utils;
import cn.hutool.core.date.DateUtil;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
/**
@ -15,14 +17,71 @@ public class TicketsOperateUtil {
/**
* 计算车龄
* @author vinjor-M
* @date 14:47 2025/1/9
* @param registerDate 车辆注册日期
* @return java.lang.Double
* @author vinjor-M
* @date 14:47 2025/1/9
**/
public Double computeCarYear(Date registerDate) {
long betweenMonth = DateUtil.betweenMonth(registerDate, new Date(), true);
String carYear = String.format("%.2f", (double) betweenMonth / 12);
return Double.parseDouble(carYear);
}
/**
* 计算利润
* @param salePrice 单个售价不含折扣
* @param purchasePrice 单个进价采购价格
* @param count 数量
* @return 利润金额
*/
public BigDecimal calcProfit(BigDecimal salePrice, BigDecimal purchasePrice, int count) {
if (salePrice == null || purchasePrice == null) {
return BigDecimal.ZERO;
}
BigDecimal c = BigDecimal.valueOf(count);
return salePrice.multiply(c).subtract(purchasePrice.multiply(c));
}
/**
* 计算利润率
* @param salePrice 单个售价不含折扣
* @param purchasePrice 单个进价采购价格
* @param count 数量
* @return 利润率0-1之间的小数保留2位
*/
public BigDecimal calcProfitRate(BigDecimal salePrice, BigDecimal purchasePrice, int count) {
if (salePrice == null || purchasePrice == null || count <= 0) {
return BigDecimal.ZERO;
}
BigDecimal c = BigDecimal.valueOf(count);
BigDecimal saleTotal = salePrice.multiply(c);
if (saleTotal.compareTo(BigDecimal.ZERO) == 0) {
return BigDecimal.ZERO;
}
BigDecimal profit = saleTotal.subtract(purchasePrice.multiply(c));
return profit.divide(saleTotal, 2, RoundingMode.HALF_UP);
}
/**
* 计算利润
* @param salePrice 单个售价不含折扣
* @param purchasePrice 单个进价采购价格
* @return 利润金额
*/
public BigDecimal calcProfit(BigDecimal salePrice, BigDecimal purchasePrice) {
return calcProfit(salePrice, purchasePrice, 1);
}
/**
* 计算利润率
* @param salePrice 售价不含折扣
* @param purchasePrice 进价采购价格
* @return 利润率0-1之间的小数保留2位
*/
public BigDecimal calcProfitRate(BigDecimal salePrice, BigDecimal purchasePrice) {
return calcProfitRate(salePrice, purchasePrice, 1);
}
}

View File

@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.tickets.entity.DlRepairTickets;
import cn.iocoder.yudao.module.tickets.entity.DlRepairTitem;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
@ -75,4 +76,10 @@ public class DlRepairTicketsRespVO extends DlRepairTickets {
/** 客户来源 */
private String cusFrom;
/** 含工时项目毛利率*/
private BigDecimal profitRate;
/** 不含工时项目毛利率*/
private BigDecimal profitRateNo;
}