gaoluyang
2 天以前 8c65f898ed6e5b0c7a94c792c4562f6ec831dccd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
package cn.iocoder.yudao.module.crm.dal.mysql.invoice;
 
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;
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoicePageReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.invoice.CrmInvoiceDO;
import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum;
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
import cn.iocoder.yudao.module.crm.util.CrmPermissionUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.ibatis.annotations.Mapper;
 
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
 
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
 
/**
 * 开票 Mapper
 *
 * @author 超级管理员
 */
@Mapper
public interface CrmInvoiceMapper extends BaseMapperX<CrmInvoiceDO> {
 
    default CrmInvoiceDO selectByNo(String no) {
        return selectOne(CrmInvoiceDO::getNo, no);
    }
 
    /**
     * 清空发票录入人、录入时间(updateById 默认忽略 null 字段,清空需显式 update)
     */
    default void clearEntryInfo(Long id) {
        update(null, new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<CrmInvoiceDO>()
                .eq(CrmInvoiceDO::getId, id)
                .set(CrmInvoiceDO::getEntryStatus, 0)
                .set(CrmInvoiceDO::getEntryUserId, null)
                .set(CrmInvoiceDO::getEntryTime, null));
    }
 
    /**
     * 按发票号码查询未被删除的开票(发票号码允许同一张发票多次开票时,返回第一条)
     */
    default CrmInvoiceDO selectByInvoiceNo(String invoiceNo) {
        return selectOne(new LambdaQueryWrapperX<CrmInvoiceDO>()
                .eq(CrmInvoiceDO::getInvoiceNo, invoiceNo)
                .orderByAsc(CrmInvoiceDO::getId)
                .last("LIMIT 1"));
    }
 
    default PageResult<CrmInvoiceDO> selectPageByCustomerId(CrmInvoicePageReqVO reqVO) {
        return selectPage(reqVO, new LambdaQueryWrapperX<CrmInvoiceDO>()
                .eq(CrmInvoiceDO::getCustomerId, reqVO.getCustomerId()) // 必须传递
                .eqIfPresent(CrmInvoiceDO::getNo, reqVO.getNo())
                .likeIfPresent(CrmInvoiceDO::getInvoiceNo, reqVO.getInvoiceNo())
                .eqIfPresent(CrmInvoiceDO::getContractId, reqVO.getContractId())
                .orderByDesc(CrmInvoiceDO::getId));
    }
 
    default PageResult<CrmInvoiceDO> selectPage(CrmInvoicePageReqVO pageReqVO, Long userId) {
        MPJLambdaWrapperX<CrmInvoiceDO> query = new MPJLambdaWrapperX<>();
        // 拼接数据权限的查询条件
        CrmPermissionUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_INVOICE.getType(),
                CrmInvoiceDO::getId, userId, pageReqVO.getSceneType());
        // 拼接自身的查询条件
        query.selectAll(CrmInvoiceDO.class)
                .eqIfPresent(CrmInvoiceDO::getNo, pageReqVO.getNo())
                .likeIfPresent(CrmInvoiceDO::getInvoiceNo, pageReqVO.getInvoiceNo())
                .eqIfPresent(CrmInvoiceDO::getContractId, pageReqVO.getContractId())
                .eqIfPresent(CrmInvoiceDO::getAuditStatus, pageReqVO.getAuditStatus())
                .orderByDesc(CrmInvoiceDO::getId);
        return selectJoinPage(pageReqVO, CrmInvoiceDO.class, query);
    }
 
    default Long selectCountByAudit(Long userId) {
        MPJLambdaWrapperX<CrmInvoiceDO> query = new MPJLambdaWrapperX<>();
        // 我负责的 + 非公海
        CrmPermissionUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_INVOICE.getType(),
                CrmInvoiceDO::getId, userId, CrmSceneTypeEnum.OWNER.getType());
        // 未审核
        query.eq(CrmInvoiceDO::getAuditStatus, CrmAuditStatusEnum.PROCESS.getStatus());
        return selectCount(query);
    }
 
    default List<CrmInvoiceDO> selectListByContractIdAndStatus(Long contractId, Collection<Integer> auditStatuses) {
        return selectList(new LambdaQueryWrapperX<CrmInvoiceDO>()
                .eq(CrmInvoiceDO::getContractId, contractId)
                .in(CrmInvoiceDO::getAuditStatus, auditStatuses));
    }
 
    default Map<Long, BigDecimal> selectInvoicePriceMapByContractId(Collection<Long> contractIds) {
        if (CollUtil.isEmpty(contractIds)) {
            return Collections.emptyMap();
        }
        // SQL sum 查询(审批通过 + 审批中,与开票防超校验口径一致)
        List<Map<String, Object>> result = selectMaps(new QueryWrapper<CrmInvoiceDO>()
                .select("contract_id, SUM(price) AS total_price")
                .in("audit_status", CrmAuditStatusEnum.APPROVE.getStatus(),
                        CrmAuditStatusEnum.PROCESS.getStatus())
                .groupBy("contract_id")
                .in("contract_id", contractIds));
        // 获得金额
        return convertMap(result, obj -> (Long) obj.get("contract_id"), obj -> (BigDecimal) obj.get("total_price"));
    }
 
    default Long selectCountByContractId(Long contractId) {
        return selectCount(CrmInvoiceDO::getContractId, contractId);
    }
 
    /**
     * 查询指定销售订单下、指定审批状态的开票
     */
    default List<CrmInvoiceDO> selectListBySaleOrderIdAndStatus(Long saleOrderId, Collection<Integer> auditStatuses) {
        return selectList(new LambdaQueryWrapperX<CrmInvoiceDO>()
                .eq(CrmInvoiceDO::getSaleOrderId, saleOrderId)
                .in(CrmInvoiceDO::getAuditStatus, auditStatuses));
    }
 
    /**
     * 查询指定销售出库单下、指定审批状态的开票
     */
    default List<CrmInvoiceDO> selectListBySaleOutIdAndStatus(Long saleOutId, Collection<Integer> auditStatuses) {
        return selectList(new LambdaQueryWrapperX<CrmInvoiceDO>()
                .eq(CrmInvoiceDO::getSaleOutId, saleOutId)
                .in(CrmInvoiceDO::getAuditStatus, auditStatuses));
    }
 
    /**
     * 批量查询多个销售订单下、指定审批状态的开票(财务对账报表使用,避免逐单查询)
     */
    default List<CrmInvoiceDO> selectListBySaleOrderIdsAndStatus(Collection<Long> saleOrderIds,
                                                                 Collection<Integer> auditStatuses) {
        if (CollUtil.isEmpty(saleOrderIds)) {
            return Collections.emptyList();
        }
        return selectList(new LambdaQueryWrapperX<CrmInvoiceDO>()
                .in(CrmInvoiceDO::getSaleOrderId, saleOrderIds)
                .in(CrmInvoiceDO::getAuditStatus, auditStatuses));
    }
 
    /**
     * 批量查询多个销售出库单下、指定审批状态的开票(财务对账报表使用,避免逐单查询)
     */
    default List<CrmInvoiceDO> selectListBySaleOutIdsAndStatus(Collection<Long> saleOutIds,
                                                               Collection<Integer> auditStatuses) {
        if (CollUtil.isEmpty(saleOutIds)) {
            return Collections.emptyList();
        }
        return selectList(new LambdaQueryWrapperX<CrmInvoiceDO>()
                .in(CrmInvoiceDO::getSaleOutId, saleOutIds)
                .in(CrmInvoiceDO::getAuditStatus, auditStatuses));
    }
 
    /**
     * 查询合同下的全部开票(导入去重用)
     */
    default List<CrmInvoiceDO> selectListByContractId(Long contractId) {
        return selectList(new LambdaQueryWrapperX<CrmInvoiceDO>()
                .eq(CrmInvoiceDO::getContractId, contractId)
                .orderByAsc(CrmInvoiceDO::getId));
    }
 
}