| | |
| | | package com.ruoyi.project.service.impl; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.text.ParseException; |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.LocalDate; |
| | | import java.time.ZoneId; |
| | | import java.time.temporal.TemporalAdjusters; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.*; |
| | | |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; |
| | | import com.ruoyi.common.exception.base.BaseException; |
| | | import com.ruoyi.common.tax.PerformanceTaxtUtils; |
| | | import com.ruoyi.common.tax.TaxtUtils; |
| | | import com.ruoyi.common.utils.bean.DtoConversionUtils; |
| | | import com.ruoyi.project.domain.*; |
| | | import com.ruoyi.project.domain.vo.TaxMoneyVO; |
| | | import com.ruoyi.project.domain.vo.TaxedMoneyVO; |
| | | import com.ruoyi.project.domain.vo.*; |
| | | import com.ruoyi.project.mapper.ServiceFundMapper; |
| | | import com.ruoyi.project.mapper.SpStatBonusMapper; |
| | | import lombok.extern.flogger.Flogger; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.project.mapper.ServiceFunddetailMapper; |
| | | import com.ruoyi.project.service.IServiceFunddetailService; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | /** |
| | | * 费用申请明细Service业务层处理 |
| | |
| | | * @author ruoyi |
| | | * @date 2022-01-25 |
| | | */ |
| | | @Slf4j |
| | | @Service |
| | | public class ServiceFunddetailServiceImpl extends ServiceImpl<ServiceFunddetailMapper, ServiceFunddetail> implements IServiceFunddetailService { |
| | | |
| | | protected final Logger logger = LoggerFactory.getLogger(this.getClass()); |
| | | @Autowired |
| | | ServiceFunddetailMapper serviceFunddetailMapper; |
| | | |
| | | @Autowired |
| | | ServiceFundMapper serviceFundMapper; |
| | | |
| | | @Autowired |
| | | SpStatBonusMapper spStatBonusMapper; |
| | | |
| | | |
| | | /** |
| | |
| | | if (serviceFunddetail.getUploadtime() != null) { |
| | | wrappers.eq(ServiceFunddetail::getUploadtime, serviceFunddetail.getUploadtime()); |
| | | } |
| | | if (serviceFunddetail.getJxrq() != null) { |
| | | wrappers.like(ServiceFunddetail::getJxrq, serviceFunddetail.getJxrq()); |
| | | } |
| | | if (StringUtils.isNotBlank(serviceFunddetail.getIdcardno())) { |
| | | wrappers.eq(ServiceFunddetail::getIdcardno, serviceFunddetail.getIdcardno()); |
| | | } |
| | | if (StringUtils.isNotBlank(serviceFunddetail.getApplytype())) { |
| | | wrappers.eq(ServiceFunddetail::getApplytype, serviceFunddetail.getApplytype()); |
| | | } |
| | | if (serviceFunddetail.getDel_flag() != null) { |
| | | wrappers.eq(ServiceFunddetail::getDel_flag, serviceFunddetail.getDel_flag()); |
| | | } |
| | | if (serviceFunddetail.getDeptId() != null) { |
| | | wrappers.eq(ServiceFunddetail::getDeptId, serviceFunddetail.getDeptId()); |
| | | } |
| | | if (serviceFunddetail.getDeptName() != null) { |
| | | wrappers.eq(ServiceFunddetail::getDeptName, serviceFunddetail.getDeptName()); |
| | | } |
| | | return this.list(wrappers); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * 根据受益人编号获取税费金额 |
| | | * 根据受益人身份证编号获取税费金额 |
| | | * |
| | | * @param taxMoneyVo |
| | | * @return |
| | |
| | | return serviceFunddetailMapper.deleteById(id); |
| | | } |
| | | |
| | | @Override |
| | | public List<ServiceFunddetailVO> getFundDetail(Long id) { |
| | | List<ServiceFunddetail> serviceFunddetails = serviceFunddetailMapper.selectFundDetailListById(id); |
| | | List<ServiceFunddetailVO> serviceFunddetailVOS = DtoConversionUtils.sourceToTarget(serviceFunddetails, ServiceFunddetailVO.class); |
| | | for (ServiceFunddetailVO serviceFunddetailVO : serviceFunddetailVOS) { |
| | | if (!StringUtils.isEmpty(serviceFunddetailVO.getAnnexfiles())) { |
| | | List<RbDetailFile> rbDetailFiles = JSONArray.parseArray(serviceFunddetailVO.getAnnexfiles(), RbDetailFile.class); |
| | | serviceFunddetailVO.setAnnexfilesList(rbDetailFiles); |
| | | } |
| | | if (!StringUtils.isEmpty(serviceFunddetailVO.getInvoicefiles())) { |
| | | List<RbDetailFile> rbDetailFiles = JSONArray.parseArray(serviceFunddetailVO.getInvoicefiles(), RbDetailFile.class); |
| | | serviceFunddetailVO.setInvoicefilesList(rbDetailFiles); |
| | | } |
| | | } |
| | | return serviceFunddetailVOS; |
| | | } |
| | | |
| | | /** |
| | | * 批量算税主方法 |
| | | * 1. 校验参数 |
| | | * 2. 排序明细,保证税时间为空的排在后面 |
| | | * 3. 遍历每条明细,分身份证号为空和不为空两种情况分别处理 |
| | | * - 身份证号为空:直接按规则赋值税后金额、税金 |
| | | * - 身份证号不为空: |
| | | * a. 查询本月第一天,获取最大序号 |
| | | * b. 查询本月累计税前、税金、税后金额 |
| | | * c. 根据"税前/税后"类型分别计算税金、税后金额 |
| | | * d. 设置算税时间、序号等 |
| | | * 4. 累计本批次总税前、税后金额 |
| | | * 5. 批量更新所有明细 |
| | | * 6. 更新主表ServiceFund的总金额、算税时间、状态 |
| | | * |
| | | * @param serviceFunddetails 费用明细列表 |
| | | * @return 是否算税成功 |
| | | */ |
| | | @Override |
| | | public Boolean calculateTax(List<ServiceFunddetail> serviceFunddetails, Map<String, TaxMoneySumEO> tempTaxSumMap) { |
| | | // 1. 校验参数 |
| | | if (CollectionUtils.isEmpty(serviceFunddetails)) { |
| | | throw new BaseException("算税条件为空,请检查后,再进行计算"); |
| | | } |
| | | // 2. 排序,税时间为空的排后面 |
| | | serviceFunddetails.sort(Comparator.comparing(obj -> ObjectUtils.isEmpty(obj.getTaxTime()) ? 1 : 0)); |
| | | |
| | | // 3. 获取本批次fundid及主表信息 |
| | | Long fundid = serviceFunddetails.get(0).getFundid(); |
| | | log.info("算税的fundid的值为:{}", fundid); |
| | | ServiceFund serviceFund1 = serviceFundMapper.selectById(fundid); |
| | | log.info("fund表的fundtextime值为:{}", serviceFund1.getFundtaxtime()); |
| | | // 4. 初始化累计金额、待更新明细列表、序号缓存、累计金额缓存 |
| | | BigDecimal pretaxcost = BigDecimal.ZERO; |
| | | BigDecimal taxedcost = BigDecimal.ZERO; |
| | | |
| | | //创建一个用于存放“需要更新到数据库的ServiceFunddetail对象”的列表 |
| | | List<ServiceFunddetail> updateList = new ArrayList<>(); |
| | | |
| | | // 5. 遍历每条明细,分情况处理 |
| | | for (ServiceFunddetail detail : serviceFunddetails) { |
| | | // 5.1 身份证号为空,直接赋值(一些人或公司,不需要算税) |
| | | if (StringUtils.isEmpty(detail.getIdcardno())) { |
| | | if (StringUtils.isEmpty(detail.getServicesscopename()) || !detail.getServicesscopename().contains("税后")) { |
| | | // 普通明细,税后金额=申请金额 |
| | | detail.setTaxedamount(detail.getAmount()); |
| | | } else { |
| | | // 税后明细,申请金额=税后金额 |
| | | detail.setAmount(detail.getTaxedamount()); |
| | | } |
| | | // 累计本批次总金额 |
| | | pretaxcost = pretaxcost.add(BigDecimal.valueOf(detail.getAmount())); |
| | | taxedcost = taxedcost.add(BigDecimal.valueOf(detail.getTaxedamount())); |
| | | detail.setTaxamount(0.0); |
| | | updateList.add(detail); |
| | | continue; |
| | | } |
| | | |
| | | // 5.2 身份证号不为空,需查历史累计金额、序号 |
| | | String idcard = detail.getIdcardno().trim(); |
| | | |
| | | // 5.2.1 查询本月累计金额(缓存避免重复查库) |
| | | TaxMoneySumEO taxSum = tempTaxSumMap.getOrDefault(idcard, null); |
| | | if (taxSum == null) { |
| | | taxSum = new TaxMoneySumEO(); |
| | | taxSum.setXh(1L); |
| | | detail.setXh(1L); |
| | | tempTaxSumMap.put(idcard, taxSum); |
| | | detail.setAllAmount(taxSum.getAmounts()); |
| | | } else { |
| | | long xh = taxSum.getXh() + 1; |
| | | taxSum.setXh(xh); |
| | | tempTaxSumMap.put(idcard, taxSum); |
| | | detail.setXh(xh); |
| | | detail.setAllAmount(taxSum.getAmounts()); |
| | | } |
| | | |
| | | // 5.2.3 算税逻辑 |
| | | if (detail.getServicesscopename().contains("税后")) { |
| | | // 税后明细:累计税后金额,反推税前金额和税金 |
| | | if (idcard.equals("330103196704060019")) { |
| | | log.info("330103196704060019"); |
| | | } |
| | | BigDecimal newTaxedAmounts = BigDecimal.valueOf(taxSum.getTaxedAmounts()).add(BigDecimal.valueOf(detail.getTaxedamount())); |
| | | String taxationBefore = TaxtUtils.getTaxationBefore(newTaxedAmounts); |
| | | BigDecimal amountNow = new BigDecimal(taxationBefore).subtract(BigDecimal.valueOf(taxSum.getAmounts())); |
| | | BigDecimal tax = amountNow.subtract(BigDecimal.valueOf(detail.getTaxedamount())); |
| | | detail.setAmount(amountNow.doubleValue()); |
| | | detail.setTaxamount(tax.doubleValue()); |
| | | if (ObjectUtils.isEmpty(serviceFund1.getFundtaxtime())) { |
| | | detail.setTaxTime(new Date()); |
| | | } else { |
| | | detail.setTaxTime(serviceFund1.getFundtaxtime()); |
| | | } |
| | | if (tax.doubleValue() < 0) { |
| | | log.info("小于0了"); |
| | | } |
| | | taxSum.setAmounts((BigDecimal.valueOf(taxSum.getAmounts()).add(amountNow)).doubleValue()); |
| | | taxSum.setTaxAmounts((BigDecimal.valueOf(taxSum.getTaxAmounts()).add(tax)).doubleValue()); |
| | | taxSum.setTaxedAmounts(newTaxedAmounts.doubleValue()); |
| | | } else { |
| | | // 税前明细:累计税前金额,算总税金,再算本次税金和税后金额 |
| | | BigDecimal newAmounts = BigDecimal.valueOf(taxSum.getAmounts()).add(BigDecimal.valueOf(detail.getAmount())); |
| | | if (idcard.equals("330103196704060019")) { |
| | | log.info("330103196704060019"); |
| | | } |
| | | String taxation = TaxtUtils.getTaxation(newAmounts); |
| | | BigDecimal taxAmountNow = new BigDecimal(taxation).subtract(new BigDecimal(String.valueOf(taxSum.getTaxAmounts()))); |
| | | BigDecimal texdAfterNow = BigDecimal.valueOf(detail.getAmount()).subtract(taxAmountNow); |
| | | detail.setTaxamount(taxAmountNow.doubleValue()); |
| | | detail.setTaxedamount(texdAfterNow.doubleValue()); |
| | | if (taxAmountNow.doubleValue() < 0) { |
| | | log.info("小于0了"); |
| | | } |
| | | |
| | | if (ObjectUtils.isEmpty(serviceFund1.getFundtaxtime())) { |
| | | detail.setTaxTime(new Date()); |
| | | } else { |
| | | detail.setTaxTime(serviceFund1.getFundtaxtime()); |
| | | } |
| | | taxSum.setAmounts(newAmounts.doubleValue()); |
| | | taxSum.setTaxAmounts((BigDecimal.valueOf(taxSum.getTaxAmounts()).add(taxAmountNow).doubleValue())); |
| | | taxSum.setTaxedAmounts((BigDecimal.valueOf(taxSum.getTaxedAmounts()).add(texdAfterNow)).doubleValue()); |
| | | } |
| | | |
| | | updateList.add(detail); |
| | | |
| | | pretaxcost = pretaxcost.add(BigDecimal.valueOf(detail.getAmount())); |
| | | taxedcost = taxedcost.add(BigDecimal.valueOf(detail.getTaxedamount())); |
| | | |
| | | } |
| | | // 6. 批量更新所有明细 |
| | | for (ServiceFunddetail d : updateList) { |
| | | this.updateById(d); |
| | | } |
| | | // 7. 更新主表ServiceFund |
| | | ServiceFund serviceFund = new ServiceFund(); |
| | | serviceFund.setPretaxcost(pretaxcost.doubleValue()); |
| | | serviceFund.setTaxedcost(taxedcost.doubleValue()); |
| | | serviceFund.setId(serviceFunddetails.get(0).getFundid()); |
| | | serviceFund.setFundtaxtime(new Date()); |
| | | |
| | | serviceFund.setIstax(1); |
| | | serviceFundMapper.updateById(serviceFund); |
| | | return true; |
| | | } |
| | | |
| | | // @Override |
| | | // public Boolean calculateTax2(List<ServiceFunddetail> serviceFunddetails) { |
| | | // //用于缓存每个身份证号(idcardno)本月累计的税前、税金、税后金额(TaxMoneySumEO对象) |
| | | // Map<String, TaxMoneySumEO> tempTaxSumMap = new HashMap<>(); |
| | | // |
| | | // TaxMoneyByItemEO taxMoneyVO = new TaxMoneyByItemEO(); |
| | | // Date firstDay = Date.from(LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()).atStartOfDay(ZoneId.systemDefault()).toInstant()); |
| | | // taxMoneyVO.setFirstDay(firstDay); |
| | | // taxMoneyVO.setTaxTime(new Date()); |
| | | // |
| | | // List<TaxMoneySumEO> taxSum = serviceFunddetailMapper.getTaxSum(taxMoneyVO); |
| | | // for (TaxMoneySumEO taxMoneySumEO : taxSum) { |
| | | // tempTaxSumMap.put(taxMoneySumEO.getIDCardNo(), taxMoneySumEO); |
| | | // } |
| | | // |
| | | // return calculateTax(serviceFunddetails, tempTaxSumMap); |
| | | // } |
| | | |
| | | |
| | | @Override |
| | | public Map<String, Double> performance(ServiceFunddetail serviceFunddetail) { |
| | | //根据"身份证号"和"绩效日期(年份)"查询个人历史绩效 |
| | | ServiceFunddetail serviceFunddetailEo = new ServiceFunddetail(); |
| | | serviceFunddetailEo.setIdcardno(serviceFunddetail.getIdcardno()); |
| | | serviceFunddetailEo.setApplytype("5"); |
| | | Calendar cal = Calendar.getInstance(); |
| | | //默认本年度 |
| | | serviceFunddetailEo.setJxrq(String.valueOf(cal.get(Calendar.YEAR))); |
| | | List<ServiceFunddetail> serviceFunddetails = queryList(serviceFunddetailEo); |
| | | |
| | | //统计历史的税 |
| | | BigDecimal historyTax = BigDecimal.valueOf(0.00); |
| | | //计算扣去每月5000的历史税前金额 |
| | | BigDecimal historyTaxBefore = BigDecimal.valueOf(0.00); |
| | | //本月是否已经算过绩效(下面扣除5000需要用到这个,如果本月已经扣过5000,就不再扣了) |
| | | Boolean deduct = false; |
| | | //获取当前月份 |
| | | Date date = new Date(); |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM"); |
| | | String nowMonth = sdf.format(date); |
| | | |
| | | for (ServiceFunddetail serviceFunddetail1 : serviceFunddetails) { |
| | | historyTaxBefore = historyTaxBefore.add(BigDecimal.valueOf(serviceFunddetail1.getAmount())).subtract(BigDecimal.valueOf(5000)); |
| | | historyTax = historyTax.add(BigDecimal.valueOf(serviceFunddetail1.getTaxamount())); |
| | | if (serviceFunddetail1.getJxrq().equals(nowMonth)) { |
| | | deduct = true; |
| | | } |
| | | } |
| | | BigDecimal allValue = BigDecimal.valueOf(0.00); |
| | | //先查询一下本月是否已经算过绩效(一个月只减一次5000,如果上一次已经减过,这一次就不在减了) |
| | | if (deduct == true) { |
| | | //本月已经减过5000了 |
| | | allValue = historyTaxBefore.add(BigDecimal.valueOf(serviceFunddetail.getAmount())); |
| | | } else { |
| | | BigDecimal subtract = BigDecimal.valueOf(serviceFunddetail.getAmount()).subtract(BigDecimal.valueOf(5000)); |
| | | allValue = historyTaxBefore.add(subtract); |
| | | } |
| | | //计算加上本次的税前金额的总税 |
| | | BigDecimal personTaxation = PerformanceTaxtUtils.getPersonTaxation(allValue); |
| | | //计算本次的税 |
| | | BigDecimal nowSingleTax = personTaxation.subtract(historyTax); |
| | | //计算本次的税后 |
| | | BigDecimal taxAfter = BigDecimal.valueOf(serviceFunddetail.getAmount()).subtract(nowSingleTax); |
| | | |
| | | //将计算出来的数据放到serviceFunddetail中 |
| | | serviceFunddetail.setTaxamount(nowSingleTax.doubleValue()); |
| | | serviceFunddetail.setTaxedamount(taxAfter.doubleValue()); |
| | | serviceFunddetail.setJxrq(nowMonth); |
| | | |
| | | save(serviceFunddetail); |
| | | Map map = new HashMap(); |
| | | map.put("amount", serviceFunddetail.getAmount()); |
| | | map.put("taxedamount", taxAfter.doubleValue()); |
| | | return map; |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public List<SpStatBonus> getListBySpStatBonus(SpStatBonusReq spStatBonusReq) { |
| | | return spStatBonusMapper.getListBySpStatBonus(spStatBonusReq.getPabegtime(), spStatBonusReq.getPaendtime(), spStatBonusReq.getPadeptno(), spStatBonusReq.getPausername(), spStatBonusReq.getPabonustype()); |
| | | } |
| | | } |