feat(quotation): 添加随机配件和交机服务功能
- 在PDF模板中添加表格样式和随机配件、交机服务表格展示 - 新增备件总价字段到购物车配件实体类 - 设置购物车VO默认系数为BigDecimal.ONE - 调整价格计算逻辑,添加折扣率处理 - 保存购物车数据到数据库 - 添加币种和汇率一致性校验 - 更新PDF导出功能的文档设置方法 - 为配件和服务请求类添加数据验证注解 - 设置配件费和服务费默认值为零 - 修改币种验证从NotBlank为NotNull - 为配件和服务列表添加@Valid注解进行嵌套验证
This commit is contained in:
parent
9a5fa93957
commit
531b3b2932
|
|
@ -173,20 +173,22 @@ public class ShoppingController extends ControllerBase {
|
|||
.setTotalFee(modelPrice.getAmount())
|
||||
.setActualFee(modelPrice.getAmount());
|
||||
log.debug("机型【{}】售价为{}", request.getModelNo(), modelPrice);
|
||||
//系数
|
||||
Pair<BigDecimal, BigDecimal> pair = getRatio(request.getModelId());
|
||||
BigDecimal standardRatio = pair.getLeft(), optionalRatio = pair.getRight(), discountRatio = BigDecimal.ONE;
|
||||
log.debug("机型【{}】标准配件系数为{},可选配件系数为{}", request.getModelNo(), standardRatio, optionalRatio);
|
||||
if (AppUserUtil.isAgent()) {
|
||||
//代理商
|
||||
QuotationDiscountDTO discountDTO = discountService.getEffectiveForCustomer(request.getModelId(), request.getTargetId(), categoryId);
|
||||
if (Objects.nonNull(discountDTO)) {
|
||||
vo.setDiscountId(discountDTO.getDiscountId());
|
||||
vo.setActualFee(vo.getTotalFee().multiply(discountDTO.getRatio()));
|
||||
vo.setDiscount(vo.getTotalFee().subtract(vo.getActualFee()));
|
||||
log.debug("机型【{}】打折后价格为{},优惠{}", request.getModelNo(), vo.getActualFee(), vo.getDiscount());
|
||||
// vo.setActualFee(vo.getTotalFee().multiply(discountDTO.getRatio()));
|
||||
// vo.setDiscount(vo.getTotalFee().subtract(vo.getActualFee()));
|
||||
// log.debug("机型【{}】打折后价格为{},优惠{}", request.getModelNo(), vo.getActualFee(), vo.getDiscount());
|
||||
discountRatio = discountDTO.getRatio();
|
||||
log.debug("机型【{}】折扣为{}", request.getModelNo(), discountRatio);
|
||||
}
|
||||
}
|
||||
//系数
|
||||
Pair<BigDecimal, BigDecimal> pair = getRatio(request.getModelId());
|
||||
BigDecimal standardRatio = pair.getLeft(), optionalRatio = pair.getRight();
|
||||
log.debug("机型【{}】标准配件系数为{},可选配件系数为{}", request.getModelNo(), standardRatio, optionalRatio);
|
||||
if (!request.getShowLowestPrice()) {
|
||||
//方案
|
||||
QuotationUserPlanModelItem planModelItem = userPlanModelItemService.getEffectiveForUser(request.getModelId(), AppUserUtil.isAgent() ? 1 : 0, AppUserUtil.getUserId());
|
||||
|
|
@ -198,13 +200,16 @@ public class ShoppingController extends ControllerBase {
|
|||
} else {
|
||||
QuotationUserPlanDefault userPlanDefault = userPlanDefaultService.getEffectiveForUser(AppUserUtil.isAgent() ? 1 : 0, AppUserUtil.getUserId());
|
||||
if (Objects.nonNull(userPlanDefault)) {
|
||||
vo.setDefaultRatio(userPlanDefault.getRatio());
|
||||
log.debug("用户方案默认系数为{}", userPlanDefault.getRatio());
|
||||
standardRatio = NumberUtil.multiply(standardRatio, userPlanDefault.getRatio());
|
||||
log.debug("机型【{}】标准配件系数为{},可选配件系数为{}", request.getModelNo(), standardRatio, optionalRatio);
|
||||
}
|
||||
}
|
||||
}
|
||||
vo.setActualFee(vo.getTotalFee().subtract(vo.getDiscount()).multiply(standardRatio));
|
||||
vo.setTotalFee(NumberUtil.multiply(vo.getTotalFee(), standardRatio));
|
||||
vo.setActualFee(NumberUtil.multiply(vo.getTotalFee(), discountRatio));
|
||||
vo.setDiscount(vo.getTotalFee().subtract(vo.getActualFee()));
|
||||
log.debug("机型【{}】价格为{},优惠{}", request.getModelNo(), vo.getActualFee(), vo.getDiscount());
|
||||
//获取部件配置
|
||||
List<ModelConfigEffectiveDTO> parts = modelConfigService.getEffectives(modelPrice.getPriceId(), categoryId, MultilingualUtil.getLanguage());
|
||||
|
|
@ -305,6 +310,7 @@ public class ShoppingController extends ControllerBase {
|
|||
).collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
shoppingCartService.save(cart);
|
||||
return ApiResult.success(cartId);
|
||||
}
|
||||
|
||||
|
|
@ -368,6 +374,10 @@ public class ShoppingController extends ControllerBase {
|
|||
.throwMessage("客户名称不一致");
|
||||
VUtils.trueThrowBusinessError(carts.stream().map(QuotationShoppingCart::getTargetId).collect(Collectors.toSet()).size() > 1)
|
||||
.throwMessage("报价对象不一致");
|
||||
VUtils.trueThrowBusinessError(carts.stream().map(QuotationShoppingCart::getCurrency).collect(Collectors.toSet()).size() > 1)
|
||||
.throwMessage("币种不一致");
|
||||
VUtils.trueThrowBusinessError(carts.stream().map(QuotationShoppingCart::getExchangeRate).collect(Collectors.toSet()).size() > 1)
|
||||
.throwMessage("汇率不一致");
|
||||
QuotationShoppingOrder order = new QuotationShoppingOrder()
|
||||
.setCreateByType(AppUserUtil.isAgent() ? 1 : 0)
|
||||
.setCreateBy(AppUserUtil.getUserName())
|
||||
|
|
@ -538,23 +548,22 @@ public class ShoppingController extends ControllerBase {
|
|||
// * 报价单-复制报价单
|
||||
// */
|
||||
// @PostMapping("/quotation/copy")
|
||||
// public ApiResult<Void> copyQuotation(@Valid @RequestBody QuotationCopyRequest request){
|
||||
// public ApiResult<Void> copyQuotation(@Valid @RequestBody QuotationCopyRequest request) {
|
||||
// QuotationShoppingOrder order = shoppingOrderService.getById(request.getId());
|
||||
// VUtils.trueThrowBusinessError(Objects.isNull(order)).throwMessage("未找到报价单");
|
||||
// List<QuotationShoppingOrderItem> orderItems = shoppingOrderItemService.lambdaQuery()
|
||||
// .eq(QuotationShoppingOrderItem::getOrderId, request.getId())
|
||||
// .list();
|
||||
// List<QuotationShoppingCart> carts = shoppingCartService.lambdaQuery()
|
||||
// .in(QuotationShoppingCart::getId, orderItems.stream().map(QuotationShoppingOrderItem::getCartId).collect(Collectors.toList()))
|
||||
// .list();
|
||||
// VUtils.trueThrowBusinessError(orderItems.size() > 1).throwMessage("多机型报价单不能复制");
|
||||
// QuotationShoppingCart cart = shoppingCartService.getById(orderItems.get(0).getCartId());
|
||||
// ShoppingCartVO vo = new ShoppingCartVO()
|
||||
// .setModelId(request.getModelId())
|
||||
// .setModelId(cart.getModelId())
|
||||
// .setTargetId(request.getTargetId())
|
||||
// .setCustomerName(request.getCustomerName())
|
||||
// .setPriceId(modelPrice.getPriceId())
|
||||
// .setConfigId(modelPrice.getConfigId())
|
||||
// .setTotalFee(modelPrice.getAmount())
|
||||
// .setActualFee(modelPrice.getAmount());
|
||||
// .setPriceId(cart.getPriceId())
|
||||
// .setConfigId(cart.getConfigId())
|
||||
// .setTotalFee(cart.getAmount())
|
||||
// .setActualFee(cart.getAmount());
|
||||
// log.debug("机型【{}】售价为{}", request.getModelNo(), modelPrice);
|
||||
// if (AppUserUtil.isAgent()) {
|
||||
// //代理商
|
||||
|
|
@ -709,7 +718,7 @@ public class ShoppingController extends ControllerBase {
|
|||
* 报价单-导出PDF
|
||||
*/
|
||||
@GetMapping("/quotation/exportToPdf")
|
||||
public void exportToPdf(HttpServletResponse response, @RequestParam @NotNull(message = "报价单id不能为空") Long id){
|
||||
public void exportToPdf(HttpServletResponse response, @RequestParam @NotNull(message = "报价单id不能为空") Long id) {
|
||||
// QuotationShoppingOrder order = shoppingOrderService.getById(id);
|
||||
// VUtils.trueThrowBusinessError(Objects.isNull(order)).throwMessage("未找到报价单");
|
||||
Map<String, Object> order = new HashMap<>();
|
||||
|
|
@ -735,7 +744,7 @@ public class ShoppingController extends ControllerBase {
|
|||
ITextRenderer renderer = new ITextRenderer();
|
||||
renderer.getFontResolver().addFont("fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
|
||||
URL baseUrl = new ClassPathResource("templates/").getURL();
|
||||
renderer.setDocumentFromString(html,baseUrl.toString());
|
||||
renderer.setDocumentFromString(html, baseUrl.toString());
|
||||
renderer.layout();
|
||||
try (OutputStream outputStream = response.getOutputStream()) {
|
||||
renderer.createPDF(outputStream);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ package com.nflg.mobilebroken.quotation.pojo.request;
|
|||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
|
|
@ -10,6 +12,7 @@ public class ShoppingSaveAccessoryRequest {
|
|||
/**
|
||||
* 物料编号
|
||||
*/
|
||||
@NotBlank
|
||||
private String materialNo;
|
||||
|
||||
/**
|
||||
|
|
@ -20,15 +23,18 @@ public class ShoppingSaveAccessoryRequest {
|
|||
/**
|
||||
* 备件数量
|
||||
*/
|
||||
@NotNull
|
||||
private Integer num;
|
||||
|
||||
/**
|
||||
* 备件单价
|
||||
*/
|
||||
@NotNull
|
||||
private BigDecimal amount;
|
||||
|
||||
/**
|
||||
* 备件总价
|
||||
*/
|
||||
@NotNull
|
||||
private BigDecimal totalAmount;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
package com.nflg.mobilebroken.quotation.pojo.request;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Null;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -100,14 +103,12 @@ public class ShoppingSaveRequest {
|
|||
/**
|
||||
* 随机配件总价
|
||||
*/
|
||||
@NotNull
|
||||
private BigDecimal accessoryFee;
|
||||
private BigDecimal accessoryFee = BigDecimal.ZERO;
|
||||
|
||||
/**
|
||||
* 交机服务总价
|
||||
*/
|
||||
@NotNull
|
||||
private BigDecimal serviceFee;
|
||||
private BigDecimal serviceFee = BigDecimal.ZERO;
|
||||
|
||||
/**
|
||||
* 交货方式,字典id
|
||||
|
|
@ -147,7 +148,7 @@ public class ShoppingSaveRequest {
|
|||
/**
|
||||
* 币种,字典id
|
||||
*/
|
||||
@NotBlank
|
||||
@NotNull
|
||||
private Long currency;
|
||||
|
||||
/**
|
||||
|
|
@ -169,10 +170,12 @@ public class ShoppingSaveRequest {
|
|||
/**
|
||||
* 随机配件
|
||||
*/
|
||||
@Valid
|
||||
private List<ShoppingSaveAccessoryRequest> accessories;
|
||||
|
||||
/**
|
||||
* 交机服务
|
||||
*/
|
||||
@Valid
|
||||
private List<ShoppingSaveServiceRequest> services;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.nflg.mobilebroken.quotation.pojo.request;
|
|||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
|
|
@ -10,20 +11,24 @@ public class ShoppingSaveServiceRequest {
|
|||
/**
|
||||
* 工程师人数
|
||||
*/
|
||||
@NotNull
|
||||
private Integer userNum;
|
||||
|
||||
/**
|
||||
* 服务天数
|
||||
*/
|
||||
@NotNull
|
||||
private Integer days;
|
||||
|
||||
/**
|
||||
* 单人天费用
|
||||
*/
|
||||
@NotNull
|
||||
private BigDecimal fee;
|
||||
|
||||
/**
|
||||
* 服务总费用
|
||||
*/
|
||||
@NotNull
|
||||
private BigDecimal totalFee;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ public class ShoppingCartVO {
|
|||
/**
|
||||
* 默认系数,没有方案时使用
|
||||
*/
|
||||
private BigDecimal defaultRatio;
|
||||
private BigDecimal defaultRatio = BigDecimal.ONE;
|
||||
|
||||
/**
|
||||
* 客户名称
|
||||
|
|
|
|||
|
|
@ -44,6 +44,16 @@
|
|||
.data1 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table, th, td {
|
||||
border: black 1px solid;
|
||||
border-collapse: collapse;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
|
@ -129,8 +139,38 @@
|
|||
<div th:text="${info.no}">其他配置</div>
|
||||
<div th:text="${info.no}">油漆要求</div>
|
||||
<div th:text="${info.no}">其它要求说明</div>
|
||||
<div th:text="${info.no}">其它要求费用</div>
|
||||
|
||||
<div th:text="${info.no}">随机配件</div>
|
||||
<table>
|
||||
<tr>
|
||||
<th>物料编号</th>
|
||||
<th>备件名称</th>
|
||||
<th>备件数量</th>
|
||||
<th>备件单价</th>
|
||||
<th>备件总金额</th>
|
||||
</tr>
|
||||
<tr th:each="item, itemStat : ${measure.items}" th:if="${not #lists.isEmpty(measure.items)}">
|
||||
<td th:text="${itemStat.index + 1}"></td>
|
||||
<td th:text="${item.name}"></td>
|
||||
<td th:text="${item.superintendent}"></td>
|
||||
<td th:text="${item.scheduleDate}"></td>
|
||||
<td th:text="${item.confirmedDate}"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div th:text="${info.no}">交机服务</div>
|
||||
<table>
|
||||
<tr>
|
||||
<th>工程师人数</th>
|
||||
<th>服务天数</th>
|
||||
<th>单人天费用</th>
|
||||
<th>服务总费用</th>
|
||||
</tr>
|
||||
<tr th:each="item, itemStat : ${measure.items}" th:if="${not #lists.isEmpty(measure.items)}">
|
||||
<td th:text="${itemStat.index + 1}"></td>
|
||||
<td th:text="${item.name}"></td>
|
||||
<td th:text="${item.superintendent}"></td>
|
||||
<td th:text="${item.scheduleDate}"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -50,6 +50,11 @@ public class QuotationShoppingCartAccessory implements Serializable {
|
|||
*/
|
||||
private BigDecimal amount;
|
||||
|
||||
/**
|
||||
* 备件总价
|
||||
*/
|
||||
private BigDecimal totalAmount;
|
||||
|
||||
/**
|
||||
* 优惠金额
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue