package com.dxhy.base.service.receipt;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dxhy.base.dao.BaseTDxRecordInvoiceDao;
import com.dxhy.base.entity.BaseTDxRecordInvoice;
import com.dxhy.base.model.BaseInvoiceReqVO;
import com.dxhy.base.model.BaseInvoiceRespVO;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.constant.DictConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.common.enums.JxszcZtEnum;
import com.dxhy.common.enums.RzztEnum;
import com.dxhy.common.service.DictdetaServcice;
import com.dxhy.common.service.TabulateRedisService;
import com.dxhy.common.service.impl.MpBaseServiceImpl;
import com.dxhy.common.util.AmountFormatUtil;
import com.dxhy.common.util.MathUtil;
import com.dxhy.common.util.StringHelper;
import com.dxhy.common.util.UserInfoUtil;
import com.dxhy.common.utils.DateUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @author peipei.li
 * @date 2019-04-23 进项税模块，底账表单表相关操作
 */
@SuppressWarnings("AlibabaUndefineMagicConstant")
@Service("baseIReceiptInvoiceService")
public class BaseReceiptInvoiceServiceImpl extends MpBaseServiceImpl<BaseTDxRecordInvoiceDao, BaseTDxRecordInvoice>
    implements BaseIReceiptInvoiceService {
    @Resource
    private TabulateRedisService tabulateRedisService;
    @Resource
    private DictdetaServcice dictdetaServcice;

    @Override
    public String listReceipt(BaseInvoiceReqVO reqVO) {
        DynamicContextHolder.push(reqVO.getUserInfo().getDbName() + DbConstant.BUSINESS_READ);

        String company = reqVO.getCompany();
        String menuId = reqVO.getMenuId();
        JSONObject json = tabulateRedisService.getTabulateMenu(company, menuId);
        // 分页参数
        Page<BaseTDxRecordInvoice> page = new Page<>(reqVO.getCurr(), reqVO.getSize());
        // 查询参数
        LambdaQueryWrapper<BaseTDxRecordInvoice> queryWrapper = createQueryWrapper(reqVO);
        // 执行查询
        IPage<BaseTDxRecordInvoice> pageInfo = super.page(page, queryWrapper);

        // 查询结果封装为view
        List<BaseInvoiceRespVO> voList = new ArrayList<>();
        int index = 1;
        for (BaseTDxRecordInvoice record : pageInfo.getRecords()) {
            BaseInvoiceRespVO vo = convertToInvoiceView(record);
            // 序号计算 = (当前页-1)*每页条数+1
            vo.setXh((page.getCurrent() - 1) * page.getSize() + index);
            index++;
            voList.add(vo);
        }

        // 设置记录总数
        json.put("total", pageInfo.getTotal());
        json.put("datalist", voList);

        // 计算合计金额 and 合计税额
        List<BaseTDxRecordInvoice> sumList = super.list(queryWrapper);
        BigDecimal tax = new BigDecimal("0");
        BigDecimal amount = new BigDecimal("0");
        for (BaseTDxRecordInvoice record : sumList) {
            // 可转出金额 = 金额 - 已转出金额
            BigDecimal bigOut = new BigDecimal(0);
            bigOut = record.getOutInvoiceAmout() == null ? bigOut : record.getOutInvoiceAmout();
            String canOutAmount = "0";
            if(ObjectUtil.isNotEmpty(record.getInvoiceAmount())){
                canOutAmount = MathUtil.sub(record.getInvoiceAmount().toPlainString(), bigOut.toPlainString());
            }

            // 可转出税额 = 税额 - 已转出税额
            BigDecimal bigTax = new BigDecimal(0);
            bigTax = record.getOutTaxAmount() == null ? bigTax : record.getOutTaxAmount();
            String canOutTax = "0";
            if(ObjectUtil.isNotEmpty(record.getDkTaxAmount())){
                canOutTax = MathUtil.sub(record.getDkTaxAmount().toPlainString(), bigTax.toPlainString());
            }
            tax = tax.add(new BigDecimal(canOutTax));
            amount = amount.add(new BigDecimal(canOutAmount));
        }

        // 合计金额 and 合计税额
        json.put("sumInvoiceAmount", AmountFormatUtil.fmtMicrometer(MathUtil.round(amount.toPlainString())));
        json.put("sumTaxAmount", AmountFormatUtil.fmtMicrometer(MathUtil.round(tax.toPlainString())));

        return super.responseResult(json);
    }

    /**
     * 批量更新 抵账表 （批量转出进项税）
     *
     * @param condList
     *            要更新的字段list
     */
    @Override
    public void updateBatch(List<BaseTDxRecordInvoice> condList) {
        for (BaseTDxRecordInvoice entity : condList) {
            LambdaUpdateWrapper<BaseTDxRecordInvoice> updateWrapper =
                new UpdateWrapper<BaseTDxRecordInvoice>().lambda();
            updateWrapper.eq(BaseTDxRecordInvoice::getId, entity.getId());
            super.update(entity, updateWrapper);
        }
        super.succResult(new JSONObject());
    }

    /**
     * 根据uuid 查询 抵账表数据
     *
     * @param uuids
     *            uuid 集合
     * @return 返回结果
     */
    @Override
    public List<BaseTDxRecordInvoice> selectByUuids(String[] uuids) {
        QueryWrapper<BaseTDxRecordInvoice> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(BaseTDxRecordInvoice::getUuid, uuids);
        return super.list(queryWrapper);
    }

    /**
     * 进项税列表，请求条件封装
     *
     * @param reqVO
     *            请求参数
     * @return 返回结果
     */
    private LambdaQueryWrapper<BaseTDxRecordInvoice> createQueryWrapper(BaseInvoiceReqVO reqVO) {
        LambdaQueryWrapper<BaseTDxRecordInvoice> queryWrapper = new QueryWrapper<BaseTDxRecordInvoice>().lambda();
        // 放查询条件的pojo
        BaseTDxRecordInvoice queryEntity = new BaseTDxRecordInvoice();
        // 转出状态为 未转出 and 部分转出
        queryWrapper.in(BaseTDxRecordInvoice::getOutStatus,
            new String[] {JxszcZtEnum.WZC.getZcztDm(), JxszcZtEnum.BFZC.getZcztDm()});
        // 认证状态为 已认证
        queryEntity.setRzhYesorno(RzztEnum.YRZ.getRzztDm());
        queryEntity.setCompany(reqVO.getCompany());
        // 购方税号
        if (!StringHelper.isBlank(reqVO.getGfsh()) && !"99".equals(reqVO.getGfsh())) {
            queryEntity.setGfTaxNo(reqVO.getGfsh());
        } else {
            List<String> allTaxNo = UserInfoUtil.getGfshAll(reqVO.getUserInfo().getOrg());
            queryWrapper.in(BaseTDxRecordInvoice::getGfTaxNo, allTaxNo);
        }
        // 发票号码
        if (!StringHelper.isBlank(reqVO.getInvoiceNo())) {
            queryEntity.setInvoiceNo(reqVO.getInvoiceNo());
        }
        // 数电号码
        if (!StringHelper.isBlank(reqVO.getEleInvoiceNo())) {
            queryEntity.setEleInvoiceNo(reqVO.getEleInvoiceNo());
        }
        // 税款所属期
        if (!StringHelper.isBlank(reqVO.getTaxPeriod())) {
            queryEntity.setRzhBelongDate(reqVO.getTaxPeriod());
        }
        // 发票状态
        if (!StringHelper.isBlank(reqVO.getInvoiceStatus()) && !"99".equals(reqVO.getInvoiceStatus())) {
            queryEntity.setInvoiceStatus(reqVO.getInvoiceStatus());
        }
        // 销方名称
        if (!StringHelper.isBlank(reqVO.getSellerName())) {
            queryWrapper.like(BaseTDxRecordInvoice::getXfName, reqVO.getSellerName());
        }
        if (reqVO.getCertStartDate() != null && reqVO.getCertEndDate() != null) {
            queryWrapper
                // 认证时间，>= 传入的startTime ，<= 传入的endTime
                .ge(BaseTDxRecordInvoice::getRzhDate,
                    DateUtils.strToDateLong(DateUtils.getMorning(reqVO.getCertStartDate())))
                .lt(BaseTDxRecordInvoice::getRzhDate,
                    DateUtils.strToDateLong(DateUtils.getNight(reqVO.getCertEndDate())));
        }
        // 业务单元代码
        if (reqVO.getBusinessCode() != null && !"99".equals(reqVO.getBusinessCode())) {
            if ("".equals(reqVO.getBusinessCode())) {
                queryWrapper.isNull(BaseTDxRecordInvoice::getDeptId);
            } else {
                queryWrapper.eq(BaseTDxRecordInvoice::getDeptId, reqVO.getBusinessCode());
            }
        }
        // 认证时间倒序
        queryWrapper.orderByDesc(BaseTDxRecordInvoice::getRzhDate);
        queryWrapper.orderByDesc(BaseTDxRecordInvoice::getInvoiceDate);
        // 条件entity放入wrapper中
        queryWrapper.setEntity(queryEntity);

        return queryWrapper;
    }

    /**
     * pojo转为vo
     *
     * @param fpxx
     *            请求参数
     * @return 返回结果
     * @author peipei
     */
    private BaseInvoiceRespVO convertToInvoiceView(BaseTDxRecordInvoice fpxx) {
        BaseInvoiceRespVO vo = new BaseInvoiceRespVO();
        // uuid作为主键
        vo.setId(fpxx.getUuid());
        // 购方税号
        vo.setGfsh(fpxx.getGfTaxNo());
        // 购方名称
        vo.setBuyerName(fpxx.getGfName());
        // 销方名称
        vo.setSellerName(fpxx.getXfName());
        // 认证日期
        vo.setCertDate(DateUtils.dateToStr(fpxx.getRzhDate()));
        // 发票代码
        vo.setInvoiceCode(fpxx.getInvoiceCode());
        // 发票号码
        vo.setInvoiceNo(fpxx.getInvoiceNo());
        //数电号码
        vo.setEleInvoiceNo(fpxx.getEleInvoiceNo());
        // 发票类型
        vo.setInvoiceType(fpxx.getInvoiceType());
        // 开票日期
        vo.setInvoiceDate(DateUtils.dateToStr(fpxx.getInvoiceDate()));
        // 发票状态
        vo.setInvoiceStatusName(dictdetaServcice.queryDictName(DictConstant.INVOICE_STATUS,fpxx.getInvoiceStatus()));
        // 税额
        if(ObjectUtil.isNotEmpty(fpxx.getTaxAmount())){
            vo.setTaxAmount(AmountFormatUtil.fmtMicrometer(MathUtil.round(fpxx.getTaxAmount().toPlainString())));
        }

        // 金额
        if(ObjectUtil.isNotEmpty(fpxx.getInvoiceAmount())){
            vo.setAmount(AmountFormatUtil.fmtMicrometer(MathUtil.round(fpxx.getInvoiceAmount().toPlainString())));
        }

        // 抵扣税额
        if(ObjectUtil.isNotEmpty(fpxx.getDkTaxAmount())){
            vo.setDkTaxAmount(AmountFormatUtil.fmtMicrometer(MathUtil.round(fpxx.getDkTaxAmount().toPlainString())));
        }

        // 可转出金额 = 金额 - 已转出金额
        BigDecimal bigOut = new BigDecimal(0);
        bigOut = fpxx.getOutInvoiceAmout() == null ? bigOut : fpxx.getOutInvoiceAmout();
        if(ObjectUtil.isNotEmpty(fpxx.getInvoiceAmount())){
            String canOutAmount = MathUtil.sub(fpxx.getInvoiceAmount().toPlainString(), bigOut.toPlainString());
            vo.setCanOutAmount(canOutAmount);
            vo.setAmount(AmountFormatUtil.fmtMicrometer(MathUtil.round(canOutAmount)));
        }

        // 可转出税额 = 税额 - 已转出税额
        BigDecimal bigTax = new BigDecimal(0);
        bigTax = fpxx.getOutTaxAmount() == null ? bigTax : fpxx.getOutTaxAmount();
        if(ObjectUtil.isNotEmpty(fpxx.getDkTaxAmount())){
            String canOutTax = MathUtil.sub(fpxx.getDkTaxAmount().toPlainString(), bigTax.toPlainString());
            vo.setCanOutTaxAmount(canOutTax);
            vo.setDkTaxAmount(AmountFormatUtil.fmtMicrometer(MathUtil.round(canOutTax)));
        }

        // 价税合计
        if(ObjectUtil.isNotEmpty(fpxx.getTotalAmount())){
            vo.setTotalAmount(AmountFormatUtil.fmtMicrometer(MathUtil.round(fpxx.getTotalAmount().toPlainString())));
        }

        return vo;
    }
}
