package com.ruoyi.account.service.impl;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.ruoyi.account.dto.DeviceTypeDetail;
|
import com.ruoyi.account.dto.DeviceTypeDistributionVO;
|
import com.ruoyi.account.mapper.BorrowInfoMapper;
|
import com.ruoyi.account.pojo.BorrowInfo;
|
import com.ruoyi.device.mapper.DeviceLedgerMapper;
|
import com.ruoyi.device.pojo.DeviceLedger;
|
import com.ruoyi.framework.web.domain.AjaxResult;
|
import com.ruoyi.procurementrecord.mapper.CustomStorageMapper;
|
import com.ruoyi.procurementrecord.mapper.ProcurementRecordMapper;
|
import com.ruoyi.procurementrecord.mapper.ProcurementRecordOutMapper;
|
import com.ruoyi.procurementrecord.pojo.CustomStorage;
|
import com.ruoyi.procurementrecord.pojo.ProcurementRecordOut;
|
import com.ruoyi.procurementrecord.pojo.ProcurementRecordStorage;
|
import com.ruoyi.procurementrecord.service.impl.ProcurementRecordOutServiceImpl;
|
import com.ruoyi.procurementrecord.service.impl.ProcurementRecordServiceImpl;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
|
import java.math.BigDecimal;
|
import java.time.LocalDateTime;
|
import java.time.Year;
|
import java.time.temporal.ChronoUnit;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
/**
|
* @author :yys
|
* @date : 2026/1/17 10:41
|
*/
|
@Service
|
@Slf4j
|
public class AccountingServiceImpl {
|
|
@Autowired
|
private DeviceLedgerMapper deviceLedgerMapper;
|
|
@Autowired
|
private BorrowInfoMapper borrowInfoMapper;
|
|
@Autowired
|
private CustomStorageMapper customStorageMapper;
|
|
@Autowired
|
private ProcurementRecordMapper procurementRecordMapper;
|
|
@Autowired
|
private ProcurementRecordOutMapper procurementRecordOutMapper;
|
|
public AjaxResult total(Integer year) {
|
Map<String,Object> map = new HashMap<>();
|
map.put("deprAmount",0); // 折旧金额
|
map.put("deviceTotal",0); // 设备总数
|
map.put("deviceAmount",0); // 设备资产原值
|
map.put("netValue",0); // 净值
|
map.put("debt",0); // 负债
|
map.put("inventoryValue",0); // 库存资产
|
LambdaQueryWrapper<DeviceLedger> deviceLedgerLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
deviceLedgerLambdaQueryWrapper.like(DeviceLedger::getCreateTime,year);
|
List<DeviceLedger> deviceLedgers = deviceLedgerMapper.selectList(deviceLedgerLambdaQueryWrapper);
|
if(CollectionUtils.isNotEmpty(deviceLedgers)){
|
map.put("deviceTotal",deviceLedgers.size());
|
BigDecimal reduce = deviceLedgers.stream()
|
.map(DeviceLedger::getTaxIncludingPriceTotal)
|
.filter(Objects::nonNull)
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
map.put("deviceAmount",reduce);
|
List<DeviceLedger> collect = deviceLedgers.stream().filter(deviceLedger -> deviceLedger.getIsDepr() != null && deviceLedger.getIsDepr() == 1).collect(Collectors.toList());
|
// 根据当前年份和设备录入时间年份比较 * 每年折旧金额 = 设备折旧金额
|
BigDecimal total = new BigDecimal(0);
|
if(CollectionUtils.isNotEmpty(collect)){
|
for (DeviceLedger deviceLedger : collect) {
|
BigDecimal totalDepreciation = calculatePreciseDepreciation(deviceLedger);
|
total = total.add(totalDepreciation);
|
}
|
map.put("deprAmount",total);
|
}
|
// 净值 = 设备资产原值 - 设备累计折旧金额
|
map.put("netValue",reduce.subtract(total));
|
}
|
// 负债
|
LambdaQueryWrapper<BorrowInfo> borrowInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
borrowInfoLambdaQueryWrapper.like(BorrowInfo::getCreateTime,year)
|
.eq(BorrowInfo::getStatus,1);
|
List<BorrowInfo> borrowInfos = borrowInfoMapper.selectList(borrowInfoLambdaQueryWrapper);
|
if(CollectionUtils.isNotEmpty(borrowInfos)){
|
BigDecimal reduce = borrowInfos.stream()
|
.map(BorrowInfo::getBorrowAmount)
|
.filter(Objects::nonNull)
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
map.put("debt",reduce);
|
}
|
// 库存资产
|
LambdaQueryWrapper<ProcurementRecordStorage> procurementRecordStorageLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
procurementRecordStorageLambdaQueryWrapper.like(ProcurementRecordStorage::getCreateTime,year);
|
List<ProcurementRecordStorage> procurementRecordStorages = procurementRecordMapper.selectList(procurementRecordStorageLambdaQueryWrapper);
|
BigDecimal procurementRecordTotal = new BigDecimal(0);
|
if(CollectionUtils.isNotEmpty(procurementRecordStorages)){
|
// 获取出库数据
|
LambdaQueryWrapper<ProcurementRecordOut> procurementRecordOutLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
procurementRecordOutLambdaQueryWrapper.like(ProcurementRecordOut::getCreateTime,year)
|
.in(ProcurementRecordOut::getProcurementRecordStorageId, procurementRecordStorages
|
.stream()
|
.map(ProcurementRecordStorage::getId)
|
.collect(Collectors.toList()))
|
.in(ProcurementRecordOut::getType,Arrays.asList(1,2));
|
List<ProcurementRecordOut> procurementRecordOuts = procurementRecordOutMapper.selectList(procurementRecordOutLambdaQueryWrapper);
|
for (ProcurementRecordStorage procurementRecordStorage : procurementRecordStorages) {
|
// 采购,生产入库总价值
|
procurementRecordTotal.add(procurementRecordStorage.getUnitPrice().multiply(procurementRecordStorage.getInboundNum()));
|
// 通过入库id,类型获取出库数据
|
List<ProcurementRecordOut> procurementRecordOutsByStorageId = procurementRecordOuts.stream()
|
.filter(procurementRecordOut -> procurementRecordOut.getProcurementRecordStorageId().equals(procurementRecordStorage.getId())
|
&& procurementRecordOut.getType().equals(procurementRecordStorage.getType()))
|
.collect(Collectors.toList());
|
if(CollectionUtils.isNotEmpty(procurementRecordOutsByStorageId)){
|
for (ProcurementRecordOut procurementRecordOut : procurementRecordOutsByStorageId) {
|
// 采购,生产出库总价值
|
procurementRecordTotal.subtract(procurementRecordStorage.getUnitPrice().multiply(procurementRecordOut.getInboundNum()));
|
}
|
}
|
|
}
|
|
|
}
|
LambdaQueryWrapper<CustomStorage> customStorageLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
customStorageLambdaQueryWrapper.like(CustomStorage::getInboundDate,year);
|
List<CustomStorage> customStorages = customStorageMapper.selectList(customStorageLambdaQueryWrapper);
|
BigDecimal customStorageTotal = new BigDecimal(0);
|
if(CollectionUtils.isNotEmpty(customStorages)){
|
// 获取出库数据
|
LambdaQueryWrapper<ProcurementRecordOut> procurementRecordOutLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
procurementRecordOutLambdaQueryWrapper.like(ProcurementRecordOut::getCreateTime,year)
|
.in(ProcurementRecordOut::getProcurementRecordStorageId, customStorages
|
.stream()
|
.map(CustomStorage::getId)
|
.collect(Collectors.toList()))
|
.eq(ProcurementRecordOut::getType,3);
|
List<ProcurementRecordOut> procurementRecordOuts = procurementRecordOutMapper.selectList(procurementRecordOutLambdaQueryWrapper);
|
customStorages.forEach(customStorage -> {
|
// 自定义入库总价值
|
customStorageTotal.add(customStorage.getTaxInclusiveUnitPrice().multiply(customStorage.getInboundNum()));
|
// 通过入库id,类型获取出库数据
|
List<ProcurementRecordOut> procurementRecordOutsByStorageId = procurementRecordOuts.stream()
|
.filter(procurementRecordOut -> procurementRecordOut.getProcurementRecordStorageId().equals(customStorage.getId()))
|
.collect(Collectors.toList());
|
if(CollectionUtils.isNotEmpty(procurementRecordOutsByStorageId)){
|
for (ProcurementRecordOut procurementRecordOut : procurementRecordOutsByStorageId) {
|
// 自定义出库总价值
|
customStorageTotal.subtract(procurementRecordOut.getInboundNum().multiply(customStorage.getTaxInclusiveUnitPrice()));
|
}
|
}
|
});
|
}
|
map.put("inventoryValue",procurementRecordTotal.add(customStorageTotal));
|
return AjaxResult.success( map);
|
}
|
|
/**
|
* 计算设备累计折旧金额
|
* @param deviceLedger 设备台账实体
|
* @return 累计折旧金额(BigDecimal,保留2位小数)
|
*/
|
public static BigDecimal calculateTotalDepreciation(DeviceLedger deviceLedger) {
|
// 1. 空值校验
|
if (deviceLedger == null) {
|
return BigDecimal.ZERO;
|
}
|
|
// 2. 判断是否开启折旧,未开启则折旧金额为0
|
Integer isDepr = deviceLedger.getIsDepr();
|
if (isDepr == null || isDepr != 1) { // 1-是 2-否
|
return BigDecimal.ZERO;
|
}
|
|
// 3. 获取每年折旧金额,为空则返回0
|
BigDecimal annualDepreciation = deviceLedger.getAnnualDepreciationAmount();
|
if (annualDepreciation == null || annualDepreciation.compareTo(BigDecimal.ZERO) <= 0) {
|
return BigDecimal.ZERO;
|
}
|
|
// 4. 获取设备录入时间,为空则返回0
|
LocalDateTime createTime = deviceLedger.getCreateTime();
|
if (createTime == null) {
|
return BigDecimal.ZERO;
|
}
|
|
// 5. 计算年份差值
|
int currentYear = Year.now().getValue(); // 当前年份
|
int createYear = createTime.getYear(); // 设备录入年份
|
int yearDiff = currentYear - createYear;
|
|
// 6. 处理年份差值为负数的情况(录入时间在未来)
|
if (yearDiff < 0) {
|
return BigDecimal.ZERO;
|
}
|
|
// 7. 计算总折旧金额 = 年份差值 * 每年折旧金额
|
BigDecimal totalDepreciation = annualDepreciation.multiply(BigDecimal.valueOf(yearDiff));
|
|
// 8. 返回保留2位小数的结果(金额规范)
|
return totalDepreciation.setScale(2, BigDecimal.ROUND_HALF_UP);
|
}
|
|
/**
|
* 【进阶版】按实际天数计算折旧(更精准)
|
* @param deviceLedger 设备台账实体
|
* @return 累计折旧金额
|
*/
|
public static BigDecimal calculatePreciseDepreciation(DeviceLedger deviceLedger) {
|
if (deviceLedger == null) {
|
return BigDecimal.ZERO;
|
}
|
|
// 判断是否开启折旧
|
Integer isDepr = deviceLedger.getIsDepr();
|
if (isDepr == null || isDepr != 1) {
|
return BigDecimal.ZERO;
|
}
|
|
// 获取每年折旧金额
|
BigDecimal annualDepreciation = deviceLedger.getAnnualDepreciationAmount();
|
if (annualDepreciation == null || annualDepreciation.compareTo(BigDecimal.ZERO) <= 0) {
|
return BigDecimal.ZERO;
|
}
|
|
// 获取设备录入时间
|
LocalDateTime createTime = deviceLedger.getCreateTime();
|
if (createTime == null) {
|
return BigDecimal.ZERO;
|
}
|
|
// 当前时间
|
LocalDateTime now = LocalDateTime.now();
|
|
// 如果录入时间在未来,返回0
|
if (createTime.isAfter(now)) {
|
return BigDecimal.ZERO;
|
}
|
|
// 计算总天数
|
long days = ChronoUnit.DAYS.between(createTime, now);
|
|
// 按每年365天计算折旧金额
|
BigDecimal dailyDepreciation = annualDepreciation.divide(BigDecimal.valueOf(365), 6, BigDecimal.ROUND_HALF_UP);
|
BigDecimal totalDepreciation = dailyDepreciation.multiply(BigDecimal.valueOf(days));
|
|
return totalDepreciation.setScale(2, BigDecimal.ROUND_HALF_UP);
|
}
|
|
public AjaxResult deviceTypeDistribution(Integer year) {
|
// 2. 组装返回VO
|
DeviceTypeDistributionVO vo = new DeviceTypeDistributionVO();
|
List<DeviceTypeDetail> details = deviceLedgerMapper.getDeviceTypeDistributionByYear( year);
|
vo.setDetails(details);
|
if(CollectionUtils.isNotEmpty(details)){
|
// 3. 提取图表所需的分类和数据
|
vo.setCategories(details.stream()
|
.map(DeviceTypeDetail::getType)
|
.collect(Collectors.toList()));
|
|
vo.setCountData(details.stream()
|
.map(DeviceTypeDetail::getCount)
|
.collect(Collectors.toList()));
|
|
vo.setAmountData(details.stream()
|
.map(DeviceTypeDetail::getAmount)
|
.collect(Collectors.toList()));
|
vo.setTotalCount(vo.getCategories().size());
|
}
|
return AjaxResult.success(vo);
|
}
|
|
public AjaxResult calculateDepreciation(Page page, Integer year) {
|
LambdaQueryWrapper<DeviceLedger> deviceLedgerLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
deviceLedgerLambdaQueryWrapper.like(DeviceLedger::getCreateTime,year)
|
.eq(DeviceLedger::getIsDepr,1);
|
IPage<DeviceLedger> deviceLedgerIPage = deviceLedgerMapper.selectPage(page, deviceLedgerLambdaQueryWrapper);
|
for (DeviceLedger record : deviceLedgerIPage.getRecords()) {
|
record.setDeprAmount(calculatePreciseDepreciation(record));
|
record.setNetValue(record.getTaxIncludingPriceTotal().subtract(record.getDeprAmount()));
|
}
|
return AjaxResult.success(deviceLedgerIPage);
|
}
|
}
|