开票功能修改

This commit is contained in:
qjq
2024-11-18 16:06:32 +08:00
parent 31bc529b42
commit 836f7d41ec
11 changed files with 114 additions and 46 deletions

View File

@ -152,5 +152,6 @@ public interface ErrorCodeConstants {
ErrorCode BILLING_NOT_EXISTS = new ErrorCode(1_004_023_00, "开票记录不存在");
ErrorCode BILLING_NOT_ORDER_EXISTS= new ErrorCode(1_004_023_00, "该时间段没有订单可开票");
ErrorCode BILLING_NOT_ORDER_REFUSE= new ErrorCode(1_004_024_00, "拒绝理由不能为空");
ErrorCode BILLING_NOT_ORDER_SECURITY= new ErrorCode(1_004_023_41, "没有权限给单位统一开票");
}

View File

@ -62,6 +62,6 @@ public class BillingPageReqVO extends PageParam {
private LocalDateTime[] createTime;
@Schema(description = "发票商品名称")
private String billingName;
@Schema(description = "单ids")
@Schema(description = "位所有开票的userid")
private String orderId;
}

View File

@ -79,6 +79,6 @@ public class BillingRespVO {
@Schema(description = "发票商品名称")
@ExcelProperty("发票商品名称")
private String billingName;
@Schema(description = "单ids")
@Schema(description = "位所有开票的userid")
private String orderId;
}

View File

@ -70,6 +70,6 @@ public class BillingSaveReqVO {
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date endTime;
@Schema(description = "单id")
@Schema(description = "位所有开票的userid")
private Set<Long> orderId;
}

View File

@ -31,7 +31,7 @@ public class AppBillingController {
@PostMapping("/create")
@Operation(summary = "创建开票记录")
public CommonResult<String> createBilling(@Valid @RequestBody BillingSaveReqVO createReqVO) {
return success(billingService.createBilling(createReqVO));
return success(billingService.createBillingUnit(createReqVO));
}
@PutMapping("/update")

View File

@ -87,7 +87,7 @@ public class BillingDO extends BaseDO {
*/
private String billingName;
/**
* 订单id 用json
* userid 用json
*/
private String orderId;
}

View File

@ -72,5 +72,12 @@ public class CardDO extends BaseDO {
* 微信充值金额
*/
private BigDecimal wxAmount;
/**
* 是否开票
*/
private Integer billingExist;
/**
* 开票编号
*/
private String billingNum;
}

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.member.dal.mysql.card;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
@ -7,16 +8,24 @@ import cn.iocoder.yudao.module.member.controller.admin.card.vo.CardPageReqVO;
import cn.iocoder.yudao.module.member.controller.app.card.vo.AppCardMonthVO;
import cn.iocoder.yudao.module.member.controller.app.card.vo.AppCardPageReqVO;
import cn.iocoder.yudao.module.member.controller.app.card.vo.FaceVo;
import cn.iocoder.yudao.module.member.dal.dataobject.billing.BillingDO;
import cn.iocoder.yudao.module.member.dal.dataobject.card.CardDO;
import cn.iocoder.yudao.module.member.enums.BillingStatusEnum;
import cn.iocoder.yudao.module.member.util.MemberConstants;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 余额变动明细 Mapper
@ -66,5 +75,25 @@ public interface CardMapper extends BaseMapperX<CardDO> {
}
return lastCardDO.getMoney();
}
default List<CardDO> getMoneyByUserIds(Collection<Long> userIds , String flag, String type,Integer var){
return selectList(new LambdaQueryWrapperX<CardDO>()
.eq(CardDO::getFlag, flag)
.eq(CardDO::getType, type)
.eq(CardDO::getBillingExist,var)
.in(CardDO::getUserId, userIds));
}
default BigDecimal getTotalMoneyByuserIds(Collection<Long> userIds, String flag, String type) {
List<CardDO> cardDOS = selectList(new LambdaQueryWrapper<CardDO>()
.eq(CardDO::getFlag, flag)
.eq(CardDO::getType, type)
.ne(CardDO::getBillingExist, BillingStatusEnum.BILLING_INVOICING_IS_COMPLETE.getCode())
.in(CardDO::getUserId, userIds));
return cardDOS.stream()
.map(CardDO::getChangeMoney)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
}

View File

@ -16,7 +16,7 @@ public enum CostTypeEnum {
MORNING("2", "早餐"),
NOON("3", "午餐"),
NIGHT("4", "晚餐"),
ADMIN_PAY("5","管理后台充值"),
ADMIN_PAY("5","现金充值"),
REFUND("6","退款"),
WITHDRAW("7","微信提现"),
CASH_WITHDRAW("8","现金提现"),

View File

@ -22,6 +22,13 @@ public interface BillingService {
*/
String createBilling(@Valid BillingSaveReqVO createReqVO);
/**
* 单位统一开票
* @param createReqVO
* @return
*/
String createBillingUnit(@Valid BillingSaveReqVO createReqVO);
/**
* 更新开票记录
*

View File

@ -12,24 +12,28 @@ import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.member.api.card.CardApi;
import cn.iocoder.yudao.module.member.controller.admin.billing.vo.BillingPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.billing.vo.BillingRespMoneyVO;
import cn.iocoder.yudao.module.member.controller.admin.billing.vo.BillingSaveReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.billing.BillingDO;
import cn.iocoder.yudao.module.member.dal.dataobject.card.CardDO;
import cn.iocoder.yudao.module.member.dal.dataobject.group.MemberGroupDO;
import cn.iocoder.yudao.module.member.dal.dataobject.order.DishOrderDO;
import cn.iocoder.yudao.module.member.dal.dataobject.orderspacecapsule.OrderSpaceCapsuleDO;
import cn.iocoder.yudao.module.member.dal.dataobject.storeorder.StoreOrderDO;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.member.dal.mysql.billing.BillingMapper;
import cn.iocoder.yudao.module.member.dal.mysql.card.CardMapper;
import cn.iocoder.yudao.module.member.dal.mysql.group.MemberGroupMapper;
import cn.iocoder.yudao.module.member.dal.mysql.order.DishOrderMapper;
import cn.iocoder.yudao.module.member.dal.mysql.orderspacecapsule.OrderSpaceCapsuleMapper;
import cn.iocoder.yudao.module.member.dal.mysql.storeorder.StoreOrderMapper;
import cn.iocoder.yudao.module.member.enums.BillingEnum;
import cn.iocoder.yudao.module.member.enums.BillingStatusEnum;
import cn.iocoder.yudao.module.member.enums.SpaceCapsuleOrderEnum;
import cn.iocoder.yudao.module.member.enums.StoreOrderStatusEnum;
import cn.iocoder.yudao.module.member.enums.*;
import cn.iocoder.yudao.module.member.service.user.MemberUserService;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@ -72,6 +76,11 @@ public class BillingServiceImpl implements BillingService {
private DishOrderMapper dishOrderMapper;
@Resource
private StoreOrderMapper storeOrderMapper;
@Resource
private MemberGroupMapper memberGroupMapper;
@Resource
private CardMapper cardMapper;
/**
* 食堂
@ -169,6 +178,42 @@ public class BillingServiceImpl implements BillingService {
// 返回主键 ID
return billing.getId();
}
@Override
@Transactional(rollbackFor = Exception.class)
public String createBillingUnit(BillingSaveReqVO createReqVO) {
Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
//校验是否为管理员
MemberGroupDO memberGroupDO = memberGroupMapper.selectOne(new LambdaQueryWrapperX<MemberGroupDO>()
.eq(MemberGroupDO::getUserId, loginUserId)
.last(" limit 1")
);
if(ObjUtil.isEmpty(memberGroupDO)) throw exception(BILLING_NOT_ORDER_SECURITY);
// 插入 BillingDO 对象并生成唯一主键
BillingDO billing = BeanUtils.toBean(createReqVO, BillingDO.class);
billing.setId(IdUtil.getSnowflakeNextId() + "");
billing.setUserName(memberGroupDO.getName());
billing.setUserPhone(String.valueOf(memberGroupDO.getId()));
billing.setUserId(loginUserId);
//查询单位充值的金额
List<CardDO> moneyByUserIds = cardMapper.getMoneyByUserIds(createReqVO.getOrderId(), CardDO.ADD, CostTypeEnum.ADMIN_PAY.getCode(),BillingStatusEnum.BILLING_INVOICING_REJECTION.getCode());
if(CollUtil.isEmpty(moneyByUserIds))throw exception(BILLING_NOT_ORDER_EXISTS);
BigDecimal totalMoney = moneyByUserIds.stream()
.map(CardDO::getChangeMoney)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
moneyByUserIds.forEach(f-> f.setBillingExist(BillingStatusEnum.BILLING_INVOICING.getCode()));
cardMapper.updateBatch(moneyByUserIds);
billing.setBillingMoney(totalMoney);
billing.setOrderId(JSONUtil.toJsonStr(createReqVO.getOrderId()));
billing.setBillingName(memberGroupDO.getName()+" 消费 "+totalMoney+"");
billing.setRequestBillingTime(LocalDateTime.now());
billing.setStatus(BillingStatusEnum.BILLING_INVOICING.getCode());
// 插入 BillingDO 对象到数据库
billingMapper.insert(billing);
// 返回主键 ID
return billing.getId();
}
// 计算订单的总金额,处理 Double 到 BigDecimal 的转换
private <T> BigDecimal calculateTotalMoney1(List<T> orders, Function<T, Double> moneyMapper) {
return orders.stream()
@ -231,20 +276,10 @@ public class BillingServiceImpl implements BillingService {
Set<Long> orderIds = jsonArray.stream()
.map(object -> Long.parseLong(object.toString())) // 将每个元素转换为 Long
.collect(Collectors.toSet());
//拒绝就把锁住的订单释放掉
switch (BillingEnum.fromCode(updateObj.getBillingType())){
case BILLING_CANTEEN:
dishOrderMapper.updateByIdBillingExist(orderIds,Boolean.FALSE);
break;
case BILLING_SUPERMARKET:
storeOrderMapper.updateByIdBillingExist(orderIds,Boolean.FALSE);
break;
case BILLING_SPACE_CAPSULE:
orderSpaceCapsuleMapper.updateByIdBillingExist(orderIds,Boolean.FALSE);
break;
default:
throw new IllegalArgumentException("Unsupported billing type");
}
LambdaUpdateChainWrapper<CardDO> wrapper = new LambdaUpdateChainWrapper<>(cardMapper);
wrapper.in(CardDO::getId,orderIds);
wrapper.set(CardDO::getBillingExist,BillingStatusEnum.BILLING_INVOICING_REJECTION.getCode());
cardMapper.update(wrapper);
}
billingMapper.updateById(updateObj);
}
@ -276,33 +311,22 @@ public class BillingServiceImpl implements BillingService {
public BillingRespMoneyVO getHaveWithoutMoney(Long userId) {
BillingRespMoneyVO b=new BillingRespMoneyVO();
//查询开票的订单
MemberGroupDO memberGroupDO = memberGroupMapper.selectOne(new LambdaQueryWrapperX<MemberGroupDO>()
.eq(MemberGroupDO::getUserId, userId)
.last(" limit 1")
);
BigDecimal reduce = billingMapper.selectList(new LambdaQueryWrapperX<BillingDO>()
.eq(BillingDO::getStatus, BillingStatusEnum.BILLING_INVOICING_IS_COMPLETE.getCode())
.eq(BillingDO::getUserId,userId)
.eq(BillingDO::getUserId,memberGroupDO.getId())
).stream()
.map(BillingDO::getBillingMoney)
.reduce(BigDecimal.ZERO, BigDecimal::add);// 求和
//获取当前单位下的所有人
List<Long> memberList = memberGroupMapper.getMemberList(memberGroupDO.getId());
//获取所有未开票的
BigDecimal moneyByUserIds = cardMapper.getTotalMoneyByuserIds(memberList, CardDO.ADD, CostTypeEnum.ADMIN_PAY.getCode());
b.setWithoutMoney(moneyByUserIds);
b.setHaveMoney(reduce);
BigDecimal reduce1 = orderSpaceCapsuleMapper.selectList(new LambdaQueryWrapperX<OrderSpaceCapsuleDO>()
.eq(OrderSpaceCapsuleDO::getStatus, SpaceCapsuleOrderEnum.SPACE_CAPSULE_ORDER_ENUM_DONE.getCode())
.eq(OrderSpaceCapsuleDO::getBillingExist, Boolean.FALSE)
.eq(OrderSpaceCapsuleDO::getUserId,userId)
)
.stream().map(OrderSpaceCapsuleDO::getMoney)
.reduce(BigDecimal.ZERO, BigDecimal::add);// 求和
BigDecimal reduce2 = dishOrderMapper.selectList(new LambdaQueryWrapperX<DishOrderDO>()
.eq(DishOrderDO::getOrderStatus, DishOrderDO.COMPLETE)
.eq(DishOrderDO::getBillingExist, Boolean.FALSE).eq(DishOrderDO::getUserId,userId))
.stream().map(DishOrderDO::getTotalMoney)
.reduce(BigDecimal.ZERO, BigDecimal::add);// 求和
BigDecimal reduce3 = storeOrderMapper.selectList(new LambdaQueryWrapperX<StoreOrderDO>()
.eq(StoreOrderDO::getStatus, StoreOrderStatusEnum.COMPLETE.getCode())
.eq(StoreOrderDO::getBillingExist, Boolean.FALSE).eq(StoreOrderDO::getUserId,userId))
.stream().map(f-> BigDecimal.valueOf(f.getTotalPrice()))
.reduce(BigDecimal.ZERO, BigDecimal::add);// 求和
BigDecimal add = reduce1.add(reduce2).add(reduce3);
b.setWithoutMoney(add);
return b;
}
}