From 25c2c9961fa433203a9df936ad27583047261d60 Mon Sep 17 00:00:00 2001
From: zss <zss@example.com>
Date: 星期六, 17 一月 2026 16:10:03 +0800
Subject: [PATCH] Merge branch 'jtwy' into dev_New
---
src/main/java/com/ruoyi/account/service/impl/AccountingServiceImpl.java | 292 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 292 insertions(+), 0 deletions(-)
diff --git a/src/main/java/com/ruoyi/account/service/impl/AccountingServiceImpl.java b/src/main/java/com/ruoyi/account/service/impl/AccountingServiceImpl.java
new file mode 100644
index 0000000..e9a586f
--- /dev/null
+++ b/src/main/java/com/ruoyi/account/service/impl/AccountingServiceImpl.java
@@ -0,0 +1,292 @@
+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 绱鎶樻棫閲戦锛圔igDecimal锛屼繚鐣�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);
+ }
+}
--
Gitblit v1.9.3