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
package com.by4cloud.platformx.business.service.impl;
 
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.by4cloud.platformx.business.dto.MeterReadRecordUpdateDTO;
import com.by4cloud.platformx.business.entity.*;
import com.by4cloud.platformx.business.mapper.*;
import com.by4cloud.platformx.business.service.MeterReadRecordService;
import com.by4cloud.platformx.common.core.util.R;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
 
import java.math.BigDecimal;
import java.util.List;
 
/**
 * 水电抄表
 *
 * @author syt
 * @date 2026-05-27 13:58:57
 */
@Service
@RequiredArgsConstructor
public class MeterReadRecordServiceImpl extends ServiceImpl<MeterReadRecordMapper, MeterReadRecord> implements MeterReadRecordService {
 
    private final ContractMapper contractMapper;
    private final ContractSubjectMatterMapper contractSubjectMatterMapper;
    private final ContractPaymentScheduleMapper contractPaymentScheduleMapper;
    private final PaymentConfirmMapper paymentConfirmMapper;
    private final ContractExecDateMapper contractExecDateMapper;
 
    @Override
    public R edit(MeterReadRecordUpdateDTO updateDTO) {
        MeterReadRecord record = baseMapper.selectById(updateDTO.getId());
        MeterReadRecord lastRecord = baseMapper.selectOne(Wrappers.<MeterReadRecord>lambdaQuery().eq(MeterReadRecord::getContractId,updateDTO.getContractId())
                .eq(MeterReadRecord::getMeterReadCode,updateDTO.getMeterReadCode()).lt(MeterReadRecord::getCreateTime,record.getCreateTime())
                .orderByDesc(MeterReadRecord::getCreateTime).last("limit 1"));
        //房屋租赁生成应收
        Contract contract = contractMapper.selectById(updateDTO.getContractId());
        ContractSubjectMatter subjectMatter = contractSubjectMatterMapper.selectById(updateDTO.getMatterId());
        if(ObjUtil.isNull(lastRecord)){
            R.failed("无合同信息,请联系技术人员");
        }
        if(ObjUtil.isNull(lastRecord)){
            return R.failed("无最近抄表记录");
        }
        if (updateDTO.getMeterReadNum().compareTo(lastRecord.getMeterReadNum())<=0){
            return R.failed("抄表数字不能比上次少");
        }
        record.setMeterReadTime(updateDTO.getMeterReadTime());
        record.setMeterReadNum(updateDTO.getMeterReadNum());
        record.setUsageNum(updateDTO.getMeterReadNum().subtract(lastRecord.getMeterReadNum()));
        record.setMeterReadAttNames(updateDTO.getMeterReadAttNames());
        record.setMeterReadAttPaths(updateDTO.getMeterReadAttPaths());
        record.setUnitPrice(subjectMatter.getUnitPrice());
        if (subjectMatter.getMaterialCode().equals("water_bill")){
            record.setMeterType("2");
        }
        if (subjectMatter.getMaterialCode().equals("electricity_bill")){
            record.setMeterType("3");
        }
        if (subjectMatter.getMaterialCode().equals("house_rental")){
            record.setMeterType("1");
        }
        record.setCostAmount(subjectMatter.getUnitPrice().multiply(updateDTO.getMeterReadNum().subtract(lastRecord.getMeterReadNum())));
        baseMapper.updateById(record);
 
        //创建收款节点
        //查询上次收款节点
        ContractPaymentSchedule lastSchedule = contractPaymentScheduleMapper.selectOne(Wrappers.<ContractPaymentSchedule>lambdaQuery()
                .eq(ContractPaymentSchedule::getContractId,contract.getId())
                .orderByDesc(ContractPaymentSchedule::getCreateTime).last("limit 1"));
        ContractPaymentSchedule schedule = new ContractPaymentSchedule();
 
        if (subjectMatter.getMaterialCode().equals("water_bill")){
            schedule.setStageName("水费代缴");
        }
        if (subjectMatter.getMaterialCode().equals("electricity_bill")){
            schedule.setStageName("电费代缴");
        }
        if (subjectMatter.getMaterialCode().equals("house_rental")){
            schedule.setStageName("房屋租赁费");
        }
        schedule.setContractId(contract.getId());
        schedule.setContractName(contract.getContractName());
        schedule.setPlannedAmount(record.getCostAmount());
        schedule.setSubjectMatterCode(subjectMatter.getMaterialCode());
        schedule.setSubjectMatterName(subjectMatter.getMaterialInternalName());
        schedule.setRemark(DateUtil.formatDate(record.getMeterReadTime())+schedule.getStageName());
        schedule.setEffectiveEndDate(updateDTO.getMeterReadTime());
        schedule.setStageOrder(1);
        if (ObjUtil.isNotNull(lastSchedule)){
            schedule.setStageOrder(lastSchedule.getStageOrder()+1);
        }
        schedule.setPaymentStatus(0);
        schedule.setActualAmount(new BigDecimal("0"));
        schedule.setInvoiceFlag("0");
        contractPaymentScheduleMapper.insert(schedule);
        //房屋租赁生成应收
        PaymentConfirm confirm = new PaymentConfirm();
        confirm.setBusinessType(subjectMatter.getMaterialInternalName()+"应收");
        confirm.setBusGuestId(contract.getPartyAId());
        confirm.setBusGuestName(contract.getPartyA());
        confirm.setContractId(contract.getId());
        confirm.setContractName(contract.getContractName());
        confirm.setContractNo(contract.getContractNo());
        confirm.setConfirmTime(updateDTO.getMeterReadTime());
        confirm.setTransationAmount(subjectMatter.getUnitPrice().multiply(updateDTO.getMeterReadNum().subtract(lastRecord.getMeterReadNum())));
        confirm.setTotalAmount(confirm.getTransationAmount().multiply(new BigDecimal("-1")));
        PaymentConfirm lastConfirm = paymentConfirmMapper.selectOne(Wrappers.<PaymentConfirm>lambdaQuery().eq(PaymentConfirm::getContractId, contract.getId())
                .orderByDesc(PaymentConfirm::getCreateTime).last("limit 1"));
        if (ObjUtil.isNotNull(lastConfirm)) {
            BigDecimal total = lastConfirm.getTotalAmount().add(confirm.getTotalAmount());
            if (total.compareTo(new BigDecimal("0")) > 0) {
                confirm.setAdvanceAmount(total);
                confirm.setTotalAmount(total);
            } else if (total.compareTo(new BigDecimal("0")) == 0) {
                confirm.setTotalAmount(total);
            } else {
                confirm.setReceivableAmount(total.multiply(new BigDecimal("-1")));
                confirm.setTotalAmount(total);
            }
            confirm.setCompId(contract.getCompId());
            paymentConfirmMapper.insert(confirm);
        } else {
            confirm.setReceivableAmount(confirm.getTransationAmount());
            confirm.setTotalAmount(confirm.getReceivableAmount().multiply(new BigDecimal("-1")));
            confirm.setCompId(contract.getCompId());
            paymentConfirmMapper.insert(confirm);
        }
        //判断 循环是否完成
        List<ContractExecDate> execDateList = contractExecDateMapper.selectList(Wrappers.<ContractExecDate>lambdaQuery().eq(ContractExecDate::getContractId,contract.getId())
                .eq(ContractExecDate::getGenFlag,"0"));
        List<MeterReadRecord> recordList = baseMapper.selectList(Wrappers.<MeterReadRecord>lambdaQuery()
                .eq(MeterReadRecord::getContractId,contract.getId())
                .isNull(MeterReadRecord::getMeterReadNum));
        if (ArrayUtil.isEmpty(execDateList.toArray())&&ArrayUtil.isEmpty(recordList.toArray())){
            List<PaymentConfirm> confirmList = paymentConfirmMapper.selectList(Wrappers.<PaymentConfirm>lambdaQuery()
                    .eq(PaymentConfirm::getContractId, contract.getId())
                    .and(wrapper -> wrapper
                            .eq(PaymentConfirm::getBusinessType, "房屋租赁应收")
                            .or()
                            .eq(PaymentConfirm::getBusinessType, "售电应收")
                            .or()
                            .eq(PaymentConfirm::getBusinessType, "不征税自来水应收")
                    ));
            if (ArrayUtil.isNotEmpty(confirmList.toArray())){
                BigDecimal total = confirmList.stream().map(PaymentConfirm::getTransationAmount).filter(amount -> amount != null).reduce(BigDecimal.ZERO, BigDecimal::add);
                contract.setAmount(total);
                contractMapper.updateById(contract);
            }
        }
        contract.setBillingStatus("2");
        contractMapper.updateById(contract);
        return R.ok();
    }
}