package com.changhong.epc.parsing.service.asset.depreciation;
|
|
import com.changhong.epc.bean.admin.AssetDepreciation;
|
import com.changhong.epc.bean.admin.CorresElField;
|
import com.changhong.epc.bean.form.Asset;
|
import com.changhong.epc.bean.form.FormBaseEntity;
|
import com.changhong.epc.bean.tenant.asset.FixedAsset;
|
import com.changhong.epc.bean.tenant.asset.FixedSummary;
|
import com.changhong.epc.bean.tenant.system.SystemConfig;
|
import com.changhong.epc.bean.tenant.system.SystemForm;
|
import com.changhong.epc.constter.exception.EPCServiceException;
|
import com.changhong.epc.parsing.mapper.tenant.asset.FixedAssetMapper;
|
import com.changhong.epc.parsing.mapper.tenant.asset.FixedSummaryMapper;
|
import com.changhong.epc.parsing.service.asset.AssetHandle;
|
import com.changhong.epc.parsing.service.asset.formula.DepreciationFactory;
|
import com.changhong.epc.parsing.service.asset.formula.YearSum;
|
import com.changhong.epc.rely.api.bean.Organization;
|
import com.changhong.epc.rely.api.epc.admin.CorresElFieldApi;
|
import com.changhong.epc.rely.api.epc.admin.asset.AssetDepreciationApi;
|
import com.changhong.epc.rely.api.epc.autoForm.FormApi;
|
import com.changhong.epc.rely.api.epc.tenant.SystemConfigApi;
|
import com.changhong.epc.rely.api.service.CscApiService;
|
import com.iemsoft.framework.cloud.core.tools.DateTool;
|
import com.iemsoft.framework.cloud.core.tools.LocalDateTool;
|
import com.iemsoft.framework.cloud.core.tools.ObjectUtil;
|
import com.iemsoft.framework.cloud.core.tools.SpringUtil;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.lang3.math.NumberUtils;
|
import org.springframework.context.annotation.Scope;
|
import org.springframework.stereotype.Service;
|
|
import javax.annotation.Resource;
|
import java.math.BigDecimal;
|
import java.text.DecimalFormat;
|
import java.time.LocalDate;
|
import java.util.List;
|
import java.util.Objects;
|
import java.util.Optional;
|
import java.util.function.Consumer;
|
|
/**
|
* 折旧处理
|
*/
|
@Service
|
@Scope("prototype")
|
@Slf4j
|
public class DepreciationHandleImpl implements AssetHandle {
|
|
@Resource
|
private FixedSummaryMapper fixedSummaryMapper;
|
|
@Resource
|
private FixedAssetMapper fixedAssetMapper;
|
|
@Resource
|
private SystemConfigApi systemConfigApi;
|
|
@Resource
|
private CorresElFieldApi corresElFieldApi;
|
|
@Resource
|
private AssetDepreciationApi assetDepreciationApi;
|
|
@Resource
|
private CscApiService cscApiService;
|
|
private String yesCode;
|
|
private String formId;
|
|
private Organization organization;
|
|
@Override
|
public boolean validate(AssetDepreciation assetDepreciation) {
|
log.debug("开始验证计提");
|
|
// 计提时间不可大于当前月份
|
if(getMonthSize(assetDepreciation.getDate(), LocalDate.now().format(LocalDateTool.getDateTimeFormat("yyyy-MM"))) < 0){
|
throw new EPCServiceException(DEPRECIATION_GT_NOW_MONTH_ERROR);
|
}
|
|
yesCode = corresElFieldApi.getVal(ASSET_IS_SECTORAL, CorresElField::getMdCode);
|
formId = systemConfigApi.getVal(SystemConfig.ofKey(FORM_INFO, SystemForm.ASSET_FORM_ID.name()), SystemConfig::getCvalue);
|
organization = cscApiService.findOneOrgByOrgCode(assetDepreciation.getOrgCode());
|
FixedSummary fixedSummary = fixedSummaryMapper.getMaxDateFixedSummary(FixedSummary.of(assetDepreciation.getOrgCode()));
|
if(fixedSummary == null){
|
// 验证当前部门时间最小的资产作为第一次计提时间
|
Asset minAsset = fixedAssetMapper.getMinDateAsset(assetDepreciation.getOrgCode(), yesCode, formId);
|
if(ObjectUtil.empty(minAsset)){
|
throw new EPCServiceException(NO_ASSET_ERROR, organization.getName());
|
}
|
if(getMonthSize(minAsset.getCapitalizationData(), assetDepreciation.getDate()) != 1){
|
throw new EPCServiceException(DEPRECIATION_MONTH_ERROR, updateMonth(minAsset.getCapitalizationData(), 1), organization.getName());
|
}
|
return true;
|
}
|
int monthSize;
|
|
// 最后一次计提时间比当前计提时间大
|
if((monthSize = getMonthSize(fixedSummary.getCalculationPeriod(), assetDepreciation.getDate())) < 0){
|
throw new EPCServiceException(DEPRECIATION_MONTH_ERROR, updateMonth(fixedSummary.getCalculationPeriod(), 1), organization.getName());
|
}
|
|
// 记账了不能重新计提
|
if(monthSize == 0 &&
|
(ObjectUtil.empty(fixedSummary.getBookkeepingState())
|
|| Objects.equals(fixedSummary.getBookkeepingState(), ACCOUNT_SUCCESS)
|
|| Objects.equals(fixedSummary.getBookkeepingState(), ACCOUNT_ING))){
|
throw new EPCServiceException(ACCOUNT_NOTEMPTY_ERROR, organization.getName(), assetDepreciation.getDate());
|
}
|
|
// 按月份顺序计提
|
if(monthSize > 1){
|
throw new EPCServiceException(DEPRECIATION_MONTH_ERROR, updateMonth(fixedSummary.getCalculationPeriod(), 1), organization.getName());
|
}
|
|
// 设置记账了才需要记账验证
|
if(assetDepreciationApi.assetIsAccount()) {
|
String lastAccount = assetDepreciationApi.selectLastAccountDate(assetDepreciation);
|
// 当前计提月份的上个月记账了,计提月份才能计提
|
if (monthSize == 1 && ObjectUtil.empty(lastAccount)
|
|| ObjectUtil.notEmpty(lastAccount) && getMonthSize(lastAccount, assetDepreciation.getDate()) != 1
|
) {
|
throw new EPCServiceException(LAST_DEPRECIATION_NOT_ACCOUNT);
|
}
|
}
|
return true;
|
}
|
|
@Override
|
public void handle(AssetDepreciation assetDepreciation) {
|
if(ObjectUtil.empty(formId)){
|
return;
|
}
|
// 查询并遍历所有资产信息
|
List<Asset> assets = fixedAssetMapper.getAllAssetByFirstOrgCode(
|
assetDepreciation.getOrgCode()
|
, assetDepreciation.getDate()
|
, null
|
, yesCode
|
, formId
|
);
|
FixedSummary fixedSummary = new FixedSummary();
|
assets.stream().forEach(asset -> forAssets(assetDepreciation, asset, fixedSummary, formId));
|
|
// 折旧成功后,修改折旧状态及其他信息
|
fixedSummary.setCountingState(DEPRECIATION_SUCCESS);
|
fixedSummary.setUseDepartment(assetDepreciation.getOrgCode());
|
fixedSummary.setCalculationPeriod(assetDepreciation.getDate());
|
fixedSummaryMapper.updateFixedSummary(fixedSummary);
|
}
|
|
public void forAssets(AssetDepreciation assetDepreciation, Asset asset, FixedSummary fixedSummary, String formId){
|
FixedAsset buffer
|
, sum = null;
|
|
/*
|
monthSize 如果等于1 说明只折旧当前月
|
monthSize 如果大于1 说明不只折旧当前月,还要和之前没有折旧的月份一起折旧
|
*/
|
// 获得需要折旧的月份
|
int monthSize = getMonthSize(getLastDepreciationTime(asset), assetDepreciation.getDate());
|
/*
|
monthSize 只可能 >= 0,不可能 < 0,因为在折旧前验证了||查询所有固定资产时已经拦截
|
*/
|
// monthSize 如果等于0 那么删除最新折旧信息,从新折旧
|
if(monthSize == 0){
|
FixedAsset fixedAsset = new FixedAsset();
|
fixedAsset.setCalculationPeriod(assetDepreciation.getDate());
|
fixedAsset.setUseDepartment(assetDepreciation.getOrgCode());
|
fixedAssetMapper.deleteFixedAsset(fixedAsset);
|
monthSize = 1;
|
}
|
|
// 资产累计折旧>0 && 实际累计折旧=0 && 折旧过
|
if(ObjectUtil.notEmpty(asset.getCpnCumulativeDepreciation())
|
&& ObjectUtil.empty(asset.getCumulativeDepreciation())
|
&& !isDepreciation(asset)){
|
// 添加历史折旧金额
|
FixedAsset fixedAsset = new FixedAsset();
|
fixedAsset.setCalculationPeriod(updateMonth(assetDepreciation.getDate(), -1));
|
fixedAsset.setAssetsCode(asset.getAssetsCode());
|
fixedAssetMapper.delete(fixedAsset);
|
mapper(asset, fixedAsset, target -> {
|
target.setCumulativeDepreciation(asset.getCpnCumulativeDepreciation());
|
target.setCurrentDepreciation(asset.getCpnCumulativeDepreciation());
|
target.setNetMoney(target.getOriginalMoney() - target.getCumulativeDepreciation());
|
});
|
// 更新资产净残值
|
asset.setNetMoney(fixedAsset.getNetMoney());
|
asset.setCumulativeDepreciation(fixedAsset.getCumulativeDepreciation());
|
// asset.setCurrentDepreciation(fixedAsset.getCumulativeDepreciation());
|
fixedAsset.setAssetsType(asset.getAssetsType());
|
fixedAsset.setAssetsTypeName(asset.getAssetsTypeName());
|
fixedAsset.setKeepingUser(asset.getKeepingUser());
|
fixedAsset.setKeepingUserName(asset.getKeepingUserName());
|
fixedAssetMapper.insertSelective(fixedAsset);
|
fixedAsset.setId(null);
|
// sum = fixedAsset;
|
}
|
// 查询未在平台折旧的累积折旧额
|
// else{
|
// sum = fixedAssetMapper.getNoDepreciationInfo(asset);
|
// }
|
|
|
for (int i = 0; i < monthSize; i++) {
|
buffer = depreciation(AssetDepreciation.of(assetDepreciation,updateMonth(assetDepreciation.getDate(), i)), asset, formId);
|
if(sum == null){
|
sum = buffer;
|
}else{
|
sum = morge(sum, buffer);
|
}
|
}
|
|
if(sum == null){
|
return;
|
}
|
int alreadyTime = 1 + Optional.ofNullable(fixedAssetMapper.getSumAlreadyTime(asset, assetDepreciation.getDate())).orElse(0);
|
int surplusTime = NumberUtils.createInteger(sum.getEstimateTime()) - alreadyTime;
|
// 更新已使用月份
|
sum.setAlreadyTime(String.valueOf(alreadyTime));
|
sum.setSurplusTime(String.valueOf(surplusTime >= 0 ? surplusTime : 0));
|
|
formatMoney(sum);
|
|
sum.setAssetsType(asset.getAssetsType());
|
sum.setAssetsTypeName(asset.getAssetsTypeName());
|
sum.setKeepingUser(asset.getKeepingUser());
|
sum.setKeepingUserName(asset.getKeepingUserName());
|
// 修改折旧信息添加记录,回写资产信息标识
|
fixedAssetMapper.updateAssetByCode(sum, formId);
|
fixedAssetMapper.insertSelective(sum);
|
// 累计本期折旧金额
|
fixedSummary.appendCurrentDepreciation(sum.getCurrentDepreciation());
|
}
|
|
private void formatMoney(FixedAsset sum) {
|
// cumulativeDepreciation
|
// netMoney
|
String assetFormId = systemConfigApi.getVal(SystemConfig.ofKey("formInfo", SystemForm.ASSET_FORM_ID.toString()), SystemConfig::getCvalue);
|
FormBaseEntity fb = SpringUtil.getBean(FormApi.class).getFormBaseEntity(assetFormId);
|
|
sum.setUpdateCumulativeDepreciation(formatDouble(fb.getFieldset(), "", sum.getCumulativeDepreciation()));
|
sum.setUpdateNetMoney(formatDouble(fb.getFieldset(), "", sum.getNetMoney()));
|
|
}
|
|
private String formatDouble(String str,String field, Double val){
|
// String str=fieldSet;
|
// Map<String,Object> map=JSONTool.toObj(str,Map.class);
|
final StringBuffer sb =new StringBuffer("#0.00");
|
// map.keySet()
|
// .stream().forEach(o->{
|
// Map<String,Object> item = JSONTool.toObj(JSONTool.toJson(map.get(o)),Map.class);
|
// Map<String,Object> tagAttribute = JSONTool.toObj(JSONTool.toJson(item.get(TAG_ATTRIBUTE)),Map.class);
|
// if(field.equalsIgnoreCase(Objects.toString(tagAttribute.get(ALIAS)))){
|
// String decimalplace = Objects.toString(tagAttribute.get(DECIMALPLACE),"0");
|
// if(decimalplace!=null && !Objects.equals("",decimalplace )){
|
// Integer s = Integer.parseInt(decimalplace);
|
// if(s != 0) {
|
// for (int i = 0; i < s; i++) {
|
// sb.append("0");
|
// }
|
// }else{
|
// sb.deleteCharAt(sb.length()-1);
|
// }
|
// }else{
|
// sb.deleteCharAt(sb.length()-1);
|
// }
|
// }
|
// });
|
String result = new DecimalFormat(sb.toString()).format(val);
|
// result = result.replaceAll("[.]$", "");
|
return result;
|
}
|
/**
|
* 合并折旧信息
|
* @param sum
|
* @param buffer
|
* @return
|
*/
|
private FixedAsset morge(FixedAsset sum, FixedAsset buffer) {
|
if(sum == null || buffer == null){
|
return sum;
|
}
|
// System.out.println("前:"+JSONTool.toJson(buffer));
|
// buffer.setCumulativeDepreciation(
|
// (sum.getCumulativeDepreciation() + buffer.getCumulativeDepreciation()) >= sum.getOriginalMoney()
|
// ? sum.getOriginalMoney()
|
// : (sum.getCumulativeDepreciation() + buffer.getCumulativeDepreciation())
|
// );
|
if(BigDecimal.valueOf(buffer.getCumulativeDepreciation()).compareTo(BigDecimal.valueOf(sum.getOriginalMoney())) == 0){
|
buffer.setCurrentDepreciation(sum.getOriginalMoney());
|
}else {
|
buffer.setCurrentDepreciation(sum.getCurrentDepreciation() + buffer.getCurrentDepreciation());
|
}
|
buffer.setNetMoney(new YearSum().toNoun(sum.getOriginalMoney() - buffer.getCumulativeDepreciation()));
|
// System.out.println("后:"+JSONTool.toJson(buffer));
|
return buffer;
|
}
|
|
private boolean isDepreciation(Asset asset){
|
return ObjectUtil.notEmpty(
|
fixedAssetMapper.getLastDepreciation(FixedAsset.of(asset.getAssetsCode()))
|
);
|
}
|
|
/**
|
* 最后一次折旧日期,没有则返回资产化日期
|
* @param asset
|
* @return
|
*/
|
private String getLastDepreciationTime(Asset asset) {
|
FixedAsset lastDepriciation = fixedAssetMapper.getLastDepreciation(FixedAsset.of(asset.getAssetsCode()));
|
if(ObjectUtil.notEmpty(lastDepriciation) && ObjectUtil.notEmpty(lastDepriciation.getCalculationPeriod())){
|
return lastDepriciation.getCalculationPeriod();
|
}
|
return DateTool.dateToString(DateTool.stringToDate(asset.getCapitalizationData(), DateTool.DATE_PATTERN), "yyyy-MM");
|
}
|
|
/**
|
* 折旧
|
* @param assetDepreciation
|
* @param asset
|
* @return
|
*/
|
public FixedAsset depreciation(AssetDepreciation assetDepreciation, Asset asset, String formId){
|
// asset = getAssetByAssetDepreciation(assetDepreciation, asset.getAssetsCode(), formId);
|
FixedAsset fixedAsset = DepreciationFactory.count(asset);
|
mapper(asset, fixedAsset, target -> target.setCalculationPeriod(assetDepreciation.getDate()));
|
return fixedAsset;
|
}
|
|
public void mapper(Asset source, FixedAsset target, Consumer<FixedAsset> filter){
|
if(source == null || target == null){
|
return;
|
}
|
target.setUseDepartmentName( organization.getName()); //组织机构名称
|
target.setSpecifications( source.getSpecifications()); //规格
|
// target.setCalculationPeriod( date); //折旧日期
|
target.setAssetsCode( source.getAssetsCode()); //物资编号
|
target.setUseDepartment( source.getUseDepartment()); //部门
|
target.setAlreadyTime( source.getAlreadyTime()); //已用年限
|
target.setSurplusTime( source.getSurplusTime()); //剩余使用年限
|
target.setAssetsName( source.getAssetsName()); //资产名称
|
target.setSpecifications( source.getSpecifications()); //规格型号
|
target.setCapitalizationData( source.getCapitalizationData()); //资产化日期
|
target.setEstimateTime( source.getEstimateTime()); //预计使用年份
|
target.setOriginalMoney( source.getOriginalMoney()); //原值
|
target.setDepreciationMethod( source.getDepreciationMethod()); //折旧方法
|
target.setAccruedTime( DateTool.currentFormatDate(DateTool.DATE_PATTERN));//计提时间
|
filter.accept(target);
|
}
|
|
Asset getAssetByAssetDepreciation(AssetDepreciation assetDepreciation, String assetCode, String formId){
|
List<Asset> assets = fixedAssetMapper.getAllAssetByFirstOrgCode(
|
assetDepreciation.getOrgCode()
|
, assetDepreciation.getDate()
|
, assetCode
|
, corresElFieldApi.getVal(ASSET_IS_SECTORAL, CorresElField::getMdCode)
|
, formId
|
);
|
if(ObjectUtil.notEmpty(assets)){
|
return assets.stream().findFirst().orElse(null);
|
}else{
|
return null;
|
}
|
}
|
|
}
|