| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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); |
| | | } |
| | | } |