费用清单入库

localizer
ljw 2025-09-26 16:28:37 +08:00
parent fc6af22c23
commit 8236f0d7aa
7 changed files with 299 additions and 10 deletions

View File

@ -0,0 +1,20 @@
package com.njzscloud.supervisory.expense.contant;
import com.njzscloud.common.core.ienum.DictStr;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
* Scope
*
*/
@Getter
@RequiredArgsConstructor
public enum Scope implements DictStr {
ALL("all", "所有客户"),
CUSTOMER_TYPE("customer_type", "客户类型"),
CUSTOMER("customer", "客户"),
;
private final String val;
private final String txt;
}

View File

@ -1,6 +1,9 @@
package com.njzscloud.supervisory.expense.pojo.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.njzscloud.common.mp.support.handler.j.JsonTypeHandler;
import com.njzscloud.supervisory.biz.constant.BizObj;
import com.njzscloud.supervisory.expense.contant.Scope;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@ -61,9 +64,20 @@ public class ExpenseItemsConfigEntity {
private Boolean canuse;
/**
* ; json
* ; ; all --> customer_type--> customer -->
*/
private String scope;
private Scope scope;
/**
*
*/
private BizObj bizObj;
/**
* ids
*/
@TableField(typeHandler = JsonTypeHandler.class)
private String companyIds;
/**
*

View File

@ -0,0 +1,14 @@
package com.njzscloud.supervisory.order.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njzscloud.supervisory.order.pojo.entity.OrderExpenseItemsEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* Mapper
*/
@Mapper
public interface OrderExpenseItemsMapper extends BaseMapper<OrderExpenseItemsEntity> {
}

View File

@ -0,0 +1,133 @@
package com.njzscloud.supervisory.order.pojo.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.njzscloud.common.mp.support.handler.j.JsonTypeHandler;
import com.njzscloud.supervisory.biz.constant.BizObj;
import com.njzscloud.supervisory.expense.contant.Scope;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
*
*/
@Getter
@Setter
@ToString
@Accessors(chain = true)
@TableName("order_expense_items")
public class OrderExpenseItemsEntity {
/**
* Id
*/
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/**
* ; expense_item_category
*/
private String expenseItemCategory;
/**
* Id
*/
private Long orderId;
/**
* Idorder_goods.id expense_items_config.id
*/
private Long originExpenseItemId;
/**
*
*/
private String expenseItemName;
/**
* ;
*/
private BigDecimal unitPrice;
/**
* ; unit
*/
private String unit;
/**
* ; money_strategy
*/
private String moneyStrategy;
/**
* Id
*/
private Long moneyConfigId;
/**
* ; ; all --> customer_type--> customer -->
*/
private Scope scope;
/**
*
*/
private BizObj bizObj;
/**
* ids
*/
@TableField(typeHandler = JsonTypeHandler.class)
private String companyIds;
/**
*
*/
private BigDecimal taxRate;
/**
*
*/
private Integer quantity;
/**
* ;
*/
private BigDecimal discountMoney;
/**
* ;
*/
private BigDecimal reviseMoney;
/**
* ;
*/
private BigDecimal settleMoney;
/**
* ;
*/
private BigDecimal totalMoney;
@TableField(fill = FieldFill.INSERT)
private Long creatorId;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long modifierId;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime modifyTime;
@TableLogic
private Boolean deleted;
}

View File

@ -0,0 +1,18 @@
package com.njzscloud.supervisory.order.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njzscloud.supervisory.order.mapper.OrderExpenseItemsMapper;
import com.njzscloud.supervisory.order.pojo.entity.OrderExpenseItemsEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* Service
*/
@Slf4j
@Service
public class OrderExpenseItemsService extends ServiceImpl<OrderExpenseItemsMapper, OrderExpenseItemsEntity> implements IService<OrderExpenseItemsEntity> {
}

View File

@ -24,6 +24,7 @@ import com.njzscloud.supervisory.biz.constant.BizObj;
import com.njzscloud.supervisory.biz.pojo.entity.BizAuditConfigEntity;
import com.njzscloud.supervisory.biz.service.BizAuditConfigService;
import com.njzscloud.supervisory.constant.Constant;
import com.njzscloud.supervisory.expense.service.ExpenseItemsConfigService;
import com.njzscloud.supervisory.order.contant.CheckStatus;
import com.njzscloud.supervisory.order.contant.OrderCategory;
import com.njzscloud.supervisory.order.contant.OrderStatus;
@ -36,12 +37,19 @@ import com.njzscloud.supervisory.order.pojo.param.*;
import com.njzscloud.supervisory.order.pojo.result.OrderCertificateResult;
import com.njzscloud.supervisory.order.pojo.result.OrderPagingResult;
import com.njzscloud.supervisory.order.pojo.result.TrainBillResult;
import com.njzscloud.supervisory.order.pojo.entity.OrderExpenseItemsEntity;
import com.njzscloud.supervisory.order.mapper.OrderExpenseItemsMapper;
import com.njzscloud.supervisory.goods.contant.MoneyStrategy;
import com.njzscloud.supervisory.expense.pojo.entity.ExpenseItemsConfigEntity;
import com.njzscloud.supervisory.expense.contant.Scope;
import com.njzscloud.supervisory.expense.contant.ExpenseItemCategory;
import com.njzscloud.supervisory.sys.auth.pojo.result.MyResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
@ -63,6 +71,8 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
private final OrderGoodsService orderGoodsService;
private final OrderCargoPlaceService orderCargoPlaceService;
private final OrderCarInOutService orderCarInOutService;
private final OrderExpenseItemsService orderExpenseItemsService;
private final ExpenseItemsConfigService expenseItemsConfigService;
/**
*
@ -480,8 +490,6 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
if (auditStatus == AuditStatus.TongGuo) {
certificateSn = SnUtil.next(CERTIFICATE_SN_CODE);
checkStatus = CheckStatus.WeiKanLiao;
// 复制数据 expense_items_config、goods_info --> order_expense_items
}
this.updateById(new OrderInfoEntity()
.setId(detail.getId())
@ -678,23 +686,105 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
Assert.isTrue(orderStatus == OrderStatus.YiJinChang, () -> Exceptions.clierr("当前订单状态,无法出场"));
baseMapper.busyDriver(orderInfoEntity.getDriverId(), Boolean.FALSE);
baseMapper.busyTruck(orderInfoEntity.getTruckId(), Boolean.FALSE);
Long orderInfoEntityId = orderInfoEntity.getId();
this.updateById(new OrderInfoEntity()
.setAutoOrder(3 ^ (i << 1))
.setId(orderInfoEntityId)
.setId(orderInfoEntity.getId())
.setOrderStatus(OrderStatus.YiChuChang)
);
OrderCategory orderCategory = orderInfoEntity.getOrderCategory();
Long truckId = orderInfoEntity.getTruckId();
// 计算本单净重(或结算重量),作为结算时的数量依据
Integer settleWeight = orderCarInOutService.truckOut(orderInfoEntity.getCarInOutId(), truckLeavingOrderParam, orderCategory, truckId);
// TODO 结算
// 结算函数orderInfoEntityIdsettleWeight
// settleWeight 重量
// 结算(目前仅针对清运公司):
// 1) 复制“产品”到 order_expense_items
// 2) 从 expense_items_config 读取可用付费项并按 scope 过滤all / customer_type=QiYe|GeTi / customer 包含 trans_company_id
// 3) 合并集合,计算 total_money 与 settle_money并批量落库。
settleForTransCompany(orderInfoEntity, settleWeight);
// TODO 关闭 GPS
}
/**
*
* 1. ExpenseItemCategory=ChanPin
* 2. scope all / customer_type=QiYe|GeTi / customer trans_company_id
* 3. total_money=quantity*unit_pricesettle_money=total_money+discount_money+revise_money
*/
private void settleForTransCompany(OrderInfoEntity orderInfoEntity, Integer settleWeight) {
Long orderId = orderInfoEntity.getId();
OrderGoodsEntity orderGoods = orderGoodsService.getById(orderInfoEntity.getGoodsId());
Assert.notNull(orderGoods, () -> Exceptions.clierr("订单产品不存在"));
// 数量口径:计费策略=按车(Che) 时数量=1否则数量=settleWeight
int quantityByStrategy = (orderGoods.getMoneyStrategy() == MoneyStrategy.Che) ? 1 : settleWeight;
// 第一步:复制产品信息为付费项记录
OrderExpenseItemsEntity productItem = new OrderExpenseItemsEntity()
.setExpenseItemCategory(ExpenseItemCategory.ChanPin.getVal())
.setOrderId(orderId)
.setOriginExpenseItemId(orderGoods.getId())
.setExpenseItemName(orderGoods.getGoodsName())
.setUnitPrice(orderGoods.getUnitPrice())
.setUnit(orderGoods.getUnit())
.setMoneyStrategy(orderGoods.getMoneyStrategy() == null ? null : orderGoods.getMoneyStrategy().getVal())
.setMoneyConfigId(orderGoods.getMoneyConfigId())
.setTaxRate(orderGoods.getTaxRate())
.setQuantity(quantityByStrategy);
// 第二步:读取启用的付费项配置,并按 scope 过滤
List<ExpenseItemsConfigEntity> configs = expenseItemsConfigService.list(Wrappers.<ExpenseItemsConfigEntity>lambdaQuery()
.eq(ExpenseItemsConfigEntity::getCanuse, Boolean.TRUE)
.eq(ExpenseItemsConfigEntity::getDeleted, Boolean.FALSE));
Long transCompanyId = orderInfoEntity.getTransCompanyId();
List<OrderExpenseItemsEntity> extraItems = configs.stream()
.filter(cfg -> {
Scope scope = cfg.getScope();
if (scope == Scope.ALL) return true;
if (scope == Scope.CUSTOMER_TYPE) {
BizObj bizObj = cfg.getBizObj();
return bizObj == BizObj.QiYe || bizObj == BizObj.GeTi;
}
if (scope == Scope.CUSTOMER) {
String companyIds = cfg.getCompanyIds();
return companyIds != null && transCompanyId != null && companyIds.contains(String.valueOf(transCompanyId));
}
return false;
})
// 复制配置为订单付费项(数量口径与产品一致:按车=1否则=settleWeight
.map(cfg -> new OrderExpenseItemsEntity()
.setExpenseItemCategory(cfg.getExpenseItemCategory())
.setOrderId(orderId)
.setOriginExpenseItemId(cfg.getId())
.setExpenseItemName(cfg.getExpenseItemName())
.setUnitPrice(cfg.getUnitPrice())
.setUnit(cfg.getUnit())
.setMoneyStrategy(cfg.getMoneyStrategy())
.setMoneyConfigId(cfg.getMoneyConfigId())
.setScope(cfg.getScope())
.setBizObj(cfg.getBizObj())
.setCompanyIds(cfg.getCompanyIds())
.setTaxRate(cfg.getTaxRate())
.setQuantity("Che".equals(cfg.getMoneyStrategy()) ? 1 : settleWeight))
.collect(Collectors.toList());
// 第三步:合并集合并计算金额,然后批量落库
extraItems.add(0, productItem);
for (OrderExpenseItemsEntity item : extraItems) {
// total_money = quantity * unit_price
BigDecimal totalMoney = item.getUnitPrice().multiply(new BigDecimal(item.getQuantity() == null ? 0 : item.getQuantity()));
// settle_money = total_money + discount_money + revise_moneydiscount、revise 可为正负)
BigDecimal discount = item.getDiscountMoney() == null ? BigDecimal.ZERO : item.getDiscountMoney();
BigDecimal revise = item.getReviseMoney() == null ? BigDecimal.ZERO : item.getReviseMoney();
BigDecimal settle = totalMoney.add(discount).add(revise);
item.setTotalMoney(totalMoney).setSettleMoney(settle);
}
orderExpenseItemsService.saveBatch(extraItems);
}
public OrderPagingResult pendingOrder(String licensePlate) {
return baseMapper.pendingOrder(Wrappers.query()
.eq("e.license_plate", licensePlate)

View File

@ -1,5 +1,5 @@
server:
port: ${APP_PORT:10086}
port: ${APP_PORT:8808}
tomcat:
max-http-form-post-size: 20MB
spring: