package com.engine.salary.service.impl;
import com.alibaba.fastjson.JSON;
import com.engine.salary.constant.SzyhApiConstant;
import com.engine.salary.entity.datacollection.bo.DataCollectionBO;
import com.engine.salary.entity.datacollection.response.QuerySpecialAmountResponse;
import com.engine.salary.entity.taxagent.po.TaxAgentTaxReturnPO;
import com.engine.salary.entity.taxagent.response.SzyhResponseHead;
import com.engine.salary.entity.taxdeclaration.po.TaxDeclarationApiConfigPO;
import com.engine.salary.entity.taxdeclaration.po.TaxDeclareRecordPO;
import com.engine.salary.entity.taxdeclaration.po.TaxDeclareStatusPO;
import com.engine.salary.entity.taxpayment.dto.TaxAgreementFeedbackResultDTO;
import com.engine.salary.entity.taxpayment.dto.TaxAmountFormDTO;
import com.engine.salary.entity.taxpayment.dto.TaxFeedbackResultDTO;
import com.engine.salary.entity.taxpayment.param.TaxPaymentQueryParam;
import com.engine.salary.entity.taxpayment.po.TaxPaymentRequestPO;
import com.engine.salary.entity.taxpayment.response.BaseResponse;
import com.engine.salary.entity.taxpayment.response.WithholdingFeedbackResponse;
import com.engine.salary.enums.SalaryOnOffEnum;
import com.engine.salary.enums.salarysob.DeclareReportTypeEnum;
import com.engine.salary.enums.taxdeclaration.TaxDeclareStatusEnum;
import com.engine.salary.enums.taxdeclaration.TaxPaymentServiceTypeEnum;
import com.engine.salary.enums.taxdeclaration.TaxPaymentStatusEnum;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.util.*;
import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
import java.util.*;
/**
* 三方缴款
*
Copyright: Copyright (c) 2023
* Company: 泛微软件
*
* @author qiantao
* @version 1.0
**/
@Slf4j
public class TaxPaymentWithholdingServiceImpl extends AbstractTaxPaymentService {
@Override
public TaxFeedbackResultDTO getFeedback(TaxPaymentQueryParam param) {
WithholdingFeedbackResponse feedbackResponse = (WithholdingFeedbackResponse) checkBeforeGetFeedbackResponse(param);
// 校验请求结果
String responseCode = Optional.ofNullable(feedbackResponse).map(WithholdingFeedbackResponse::getHead).map(SzyhResponseHead::getCode).orElse(null);
String msg = Optional.ofNullable(feedbackResponse).map(WithholdingFeedbackResponse::getHead).map(SzyhResponseHead::getMsg).orElse(null);
if (SzyhApiConstant.HANDLING_CODE.equals(responseCode)) {
// 如果接口仍在处理中,则继续轮询
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(175337, "缴款还在处理中,请稍后点击缴款反馈"));
}
// 获取返回的人员信息列表
if (!SzyhApiConstant.SUCCESS_CODE.equals(responseCode)) {
log.info("getAgreementQueryFeedbackResponse not success: {}", JSON.toJSONString(feedbackResponse));
throw new SalaryRunTimeException(msg);
}
List statuses = getTaxDeclareRecordService(user).getTaxDeclareStatusByTaxDeclareRecordId(param.getTaxDeclareRecordId());
for (TaxDeclareStatusPO status : statuses) {
WithholdingFeedbackResponse.Feedback feedback = Optional.of(feedbackResponse)
.map(WithholdingFeedbackResponse::getBody)
.map(body -> {
if (Objects.equals(status.getReportType(), DeclareReportTypeEnum.COMPREHENSIVE_INCOME.getValue())) {
return body.getZhsdjk();
} else if (Objects.equals(status.getReportType(), DeclareReportTypeEnum.CLASSIFIED_INCOME.getValue())) {
return body.getFlsdjk();
} else if (Objects.equals(status.getReportType(), DeclareReportTypeEnum.NONRESIDENT_INCOME.getValue())) {
return body.getFjmsdjk();
} else {
return body.getXsgsdjk();
}
})
.orElse(null);
if (feedback == null) {
log.info("getAgreementQueryFeedbackResponse empty data error: {}", JSON.toJSONString(feedbackResponse));
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(175338, "税局接口错误,未返回有效数据"));
}
// 判断缴款状态是否成功
Integer paymentStatus = SalaryEntityUtil.getIntValue(feedback.getJkzt(), -1);
TaxPaymentStatusEnum paymentStatusEnum = SalaryEnumUtil.enumMatchByValue(paymentStatus, TaxPaymentStatusEnum.class);
if (paymentStatusEnum != TaxPaymentStatusEnum.SUCCESS) {
// fixme
throw new SalaryRunTimeException(String.format("缴款失败,失败原因:%s,申报状态:%s", feedback.getJksbyy(), feedback.getSbzt()));
}
// 累计实缴金额
BigDecimal totalPaid = feedback.getKkfhlb().stream().map(e -> new BigDecimal(e.getSjse())).reduce(BigDecimal.ZERO, BigDecimal::add);
if (TaxDeclareStatusEnum.DECLARE_SUCCESS_PAID.getValue().equals(status.getTaxDeclareStatus())) {
throw new SalaryRunTimeException("当前申报表状态为已缴款,无法更新状态");
}
BigDecimal taxPayAmount = SalaryEntityUtil.empty2Zero(status.getTaxPayAmount());
BigDecimal taxPurePaidAmount = SalaryEntityUtil.empty2Zero(status.getTaxPurePaidAmount());
if (SalaryEntityUtil.empty2Zero(status.getTaxPaidAmount()).equals(totalPaid)
&& taxPayAmount.compareTo(BigDecimal.ZERO) > 0) {
throw new SalaryRunTimeException("请进行缴款后再刷新缴款状态");
}
status.setTaxDeclareStatus(TaxDeclareStatusEnum.DECLARE_SUCCESS_PAID.getValue());
status.setTaxPaidAmount(totalPaid.toString());
status.setTaxPurePaidAmount(taxPurePaidAmount.add(taxPayAmount).toString());
status.setTaxPayAmount(BigDecimal.ZERO.toString());
getTaxDeclareStatusService(user).updateTaxDeclareStatus(status, false);
}
TaxAmountFormDTO taxAmountFormDTO = queryTaxAmount(param);
//更新主记录
getTaxDeclareStatusService(user).updateRecord(param.getTaxDeclareRecordId());
// 更新缴款请求为已反馈
updateTaxPaymentRequest(param);
TaxDeclareRecordPO declareRecordPO = getTaxDeclareRecordService(user).getById(param.getTaxDeclareRecordId());
BigDecimal otherAmount = SalaryEntityUtil.empty2Zero(declareRecordPO.getTaxPaidAmount()).subtract(SalaryEntityUtil.empty2Zero(declareRecordPO.getTaxPurePaidAmount()));
return new TaxAgreementFeedbackResultDTO()
.setPayAmount(SalaryEntityUtil.thousandthConvert(SalaryEntityUtil.empty2Zero(declareRecordPO.getTaxPaidAmount()).toString()))
.setOtherAmount(SalaryEntityUtil.thousandthConvert(otherAmount.toString()))
.setPersonNum(taxAmountFormDTO.getPersonNum());
}
@Override
public Integer getServiceType() {
return TaxPaymentServiceTypeEnum.WITHHOLDING_PAY.getValue();
}
protected T getRequestIdResponse(TaxAgentTaxReturnPO returnPO,
String taxAgentName,
TaxPaymentQueryParam param,
TaxDeclarationApiConfigPO apiConfig,
Class clazz) {
SalaryAssert.notBlank(param.getProtocolNumber(), SalaryI18nUtil.getI18nLabel(184071, "三方缴费参数错误"));
String url = apiConfig.getHost() + SzyhApiConstant.DECLARE_WITH_HOLDING;
Map requestParam = DataCollectionBO.getApiBaseQueryParams(returnPO, taxAgentName, SalaryDateUtil.getFormatYYYYMM(param.getTaxYearMonth()));
requestParam.put("sfxyh", param.getProtocolNumber());
// requestParam.put("ynse", param.getTaxAmount());
// requestParam.put("sblx", "1");
return postRequest(apiConfig, url, requestParam, clazz);
}
@Override
protected TempWrapper checkBeforeGetRequestIdResponse(TaxPaymentQueryParam param) {
TempWrapper tempWrapper = super.checkBeforeGetRequestIdResponse(param);
Map requestParam = DataCollectionBO.getApiBaseQueryParams(tempWrapper.getTaxReturnPO(), tempWrapper.getTaxAgentPO().getName(), SalaryDateUtil.getFormatYYYYMM(param.getTaxYearMonth()));
requestParam.put("sblx", param.getReportType());
cancelWithholdingVoucher(tempWrapper.getApiConfigPO(), tempWrapper.getTaxDeclareRecord(), requestParam);
return tempWrapper;
}
@Override
public void cancelWithholdingVoucher(TaxDeclarationApiConfigPO apiConfig, TaxDeclareRecordPO taxDeclareRecord, Map requestParam) {
TaxPaymentRequestPO paymentRequestPO = getTaxPaymentRequestMapper().getOne(TaxPaymentRequestPO
.builder()
.requestType(TaxPaymentServiceTypeEnum.WITHHOLDING_VOUCHER.getValue())
.taxAgentId(taxDeclareRecord.getTaxAgentId())
.taxYearMonth(taxDeclareRecord.getTaxCycle())
.build());
// if (paymentRequestPO != null) {
String url = apiConfig.getHost() + SzyhApiConstant.CANCEL_WITHHOLDING_VOUCHER;
QuerySpecialAmountResponse cancelResponse = postRequest(apiConfig, url, requestParam, QuerySpecialAmountResponse.class);
SzyhResponseHead head = Optional.ofNullable(cancelResponse).map(QuerySpecialAmountResponse::getHead)
.orElse(new SzyhResponseHead("0", SalaryI18nUtil.getI18nLabel(183785, "银联缴款凭证作废失败,请稍后重试")));
SalaryAssert.isTrue(SzyhApiConstant.SUCCESS_CODE.equals(head.getCode())
|| SzyhApiConstant.NONE_VOUCHER_CODE.equals(head.getCode()), head.getMsg());
getTaxPaymentRequestMapper().updateFeedbackByRequestTypeTaxAgentIdTaxYearMonth(TaxPaymentRequestPO
.builder()
.feedback(SalaryOnOffEnum.ON.getValue())
.requestType(TaxPaymentServiceTypeEnum.WITHHOLDING_VOUCHER.getValue())
.taxAgentId(taxDeclareRecord.getTaxAgentId())
.taxYearMonth(taxDeclareRecord.getTaxCycle())
.build());
// }
}
protected BaseResponse getFeedbackResponse(TaxDeclarationApiConfigPO apiConfig, String requestId) {
String url = apiConfig.getHost() + SzyhApiConstant.DECLARE_WITH_HOLDING_FEEDBACK;
String res = getRequest(apiConfig, requestId, url);
return JsonUtil.parseObject(res, WithholdingFeedbackResponse.class);
}
}