package com.ruoyi.orderManagement.finance.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.basicData.domain.TCorps;
import com.ruoyi.basicData.domain.TFees;
import com.ruoyi.basicData.mapper.TCorpsMapper;
import com.ruoyi.basicData.mapper.TFeesMapper;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.orderManagement.finance.domain.FTmsaccbills;
import com.ruoyi.orderManagement.finance.domain.FTmsaccbillsFees;
import com.ruoyi.orderManagement.finance.domain.FTmsaccbillsitems;
import com.ruoyi.orderManagement.finance.mapper.FTmsaccbillsMapper;
import com.ruoyi.orderManagement.finance.mapper.FTmsaccbillsitemsMapper;
import com.ruoyi.orderManagement.finance.service.IFTmsaccbillsService;
import com.ruoyi.orderPlan.mapper.FtmsorderbillsMapper;
import com.ruoyi.orderPlan.mapper.FtmsorderbillscarsMapper;
import com.ruoyi.orderPlan.mapper.FtmsorderbillsfeesMapper;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.warehouseBusiness.domain.BillnoDel;
import com.ruoyi.warehouseBusiness.mapper.BillnoDelMapper;
import com.ruoyi.warehouseBusiness.service.impl.BillnoSerialServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.util.*;


/**
 * 财务主Service业务层处理
 *
 * @author ruoyi
 * @date 2021-03-12
 */
@Service
public class FTmsaccbillsServiceImpl implements IFTmsaccbillsService {
    @Autowired
    private FTmsaccbillsMapper fTmsaccbillsMapper;

    @Autowired
    private BillnoDelMapper billnoDelMapper;

    @Autowired
    private BillnoSerialServiceImpl billnoSerialServiceImpl;

    @Autowired
    private FTmsaccbillsitemsMapper fTmsaccbillsitemsMapper;

    @Autowired
    private FtmsorderbillsfeesMapper ftmsorderbillsfeesMapper;

    @Autowired
    private FtmsorderbillsMapper ftmsorderbillsMapper;

    @Autowired
    private FtmsorderbillscarsMapper ftmsorderbillscarsMapper;

    @Autowired
    private TCorpsMapper tCorpsMapper;

    @Autowired
    private TFeesMapper tFeesMapper;

    @Autowired
    private ISysDictDataService iSysDictDataService;

    @Override
    public Map<String, Object> selectFTmsaccbillsAndItemsById(Long fId) {
        Map<String, Object> map = new HashMap<>();
        // 客户表
        List<Long> corpsId = new ArrayList<>();
        // 费用
        List<Long> feesId = new ArrayList<>();
        FTmsaccbills fTmsaccbills = fTmsaccbillsMapper.selectFTmsaccbillsById(fId);
        if (StringUtils.isNotNull(fTmsaccbills.getfCorpid())) {
            corpsId.add(fTmsaccbills.getfCorpid());
        }
        // 查询从表数据
        /*FTmsaccbillsitems fTmsaccbillsitems = new FTmsaccbillsitems();
        fTmsaccbillsitems.setFPid(fId);
        List<FTmsaccbillsitems> fTmsaccbillsitemsList = fTmsaccbillsitemsMapper.selectFTmsaccbillsitemsList(fTmsaccbillsitems);
        if (StringUtils.isNotEmpty(fTmsaccbillsitemsList)) {
            for (FTmsaccbillsitems fees : fTmsaccbillsitemsList) {
                Map<String, Object> map1 = new HashMap<>();
                // 主表数
                Ftmsorderbills ftmsorderbills = ftmsorderbillsMapper.selectftmsorderbillsById(fees.getFSrcpid());
                Ftmsorderbillsfees ftmsorderbillsfees = ftmsorderbillsfeesMapper.selectFTmsorderbillsfeesById(fees.getFSrcid());
                TFees tFees = new TFees();
                if (null != ftmsorderbillsfees.getfFeeid()) {
                    tFees = tFeesMapper.selectTFeesById(ftmsorderbillsfees.getfFeeid());
                }
                if (ftmsorderbillsfees.getActId() == 1080L || ftmsorderbillsfees.getActId() == 1090L) {
                    Ftmsorderbillscars ftmsorderbillscars = ftmsorderbillscarsMapper.selectftmsorderbillscarsById(ftmsorderbillsfees.getfPid());
                    if (StringUtils.isNotNull(ftmsorderbillscars.getLoadDate())) {
                        map1.put("carLoadDate", DateUtils.dateTime(ftmsorderbillscars.getLoadDate()));
                    }
                }
                // 字典宝
                SysDictData sysDictData = new SysDictData();
                sysDictData.setDictType("data_unitfees");
                sysDictData.setDictValue(String.valueOf(ftmsorderbillsfees.getfFeeunitid()));
                sysDictData.setStatus("0");
                List<SysDictData> sysDictDataList = iSysDictDataService.selectDictDataList(sysDictData);
                map1.put("fSrcpid", fees.getFSrcpid());  //  主表ID
                map1.put("fName", ftmsorderbills.getCorpId());//  客户
                corpsId.add(ftmsorderbills.getCorpId());
                map1.put("fSrcid", fees.getFSrcid()); // 费用ID
                map1.put("fFeesName", ftmsorderbillsfees.getfCorpid());// 结算单位
                corpsId.add(ftmsorderbillsfees.getfCorpid());
                map1.put("fMblno", ftmsorderbills.getMblno()); //提单号
                map1.put("fProductName", ftmsorderbillsfees.getfProductName()); //提单号
                map1.put("fBsdate", ftmsorderbillsfees.getCreateTime()); //业务日期
                map1.put("actId", ftmsorderbillsfees.getActId()); // 业务类型
                map1.put("billType", ftmsorderbills.getBillType()); // 作业类型
                if (null != tFees.getfName()) {
                    map1.put("fFeeName", tFees.getfName()); // 作业类型
                } else {
                    map1.put("fFeeName", null); // 作业类型
                }
                feesId.add(ftmsorderbillsfees.getfFeeunitid());
                map1.put("fSrcdc", fees.getDc()); // 收付
                map1.put("fAmt", fees.getFAmt()); // 数量
                map1.put("fAmtdr", fees.getFAmtdr()); // 金额
                map1.put("fQty", ftmsorderbillsfees.getfQty()); // 数量
                map1.put("fAmount", fees.getAmtOrg()); // 金额
                map1.put("amtCur", fees.getAmtCur()); // 金额
                map1.put("fFeeunitid", sysDictDataList.get(0).getDictLabel()); //计价单位
                map1.put("loadDate", ftmsorderbills.getLoadDate()); // 计费开始日期
                map1.put("unLoadDate", ftmsorderbills.getUnLoadDate()); //计费截止日期
                feeDoList.add(map1);
            }
        }*/
        List<TCorps> corpsList = new ArrayList<>();
        List<Long> corpsIdList = StringUtils.integerDeduplication(corpsId);
        for (Long corpId : corpsIdList) {
            TCorps corps = tCorpsMapper.selectTCorpsById(corpId);
            if (StringUtils.isNotNull(corps)) {
                corpsList.add(corps);
            }
        }
        List<TFees> feesList = new ArrayList<>();
        List<Long> longList = StringUtils.integerDeduplication(feesId);
        for (Long fees : longList) {
            TFees tFees = tFeesMapper.selectTFeesById(fees);
            if (StringUtils.isNotNull(tFees)) {
                feesList.add(tFees);
            }
        }
        map.put("tFee", fTmsaccbills);
        map.put("corps", corpsList);
        map.put("feesList", feesList);
        map.put("feeDoList", fTmsaccbillsitemsMapper.selectItemsMapById(fId));
        return map;
    }

    @Override
    public List<Map<String, Object>> selectFTmsaccbillsMapList(FTmsaccbills fTmsaccbills) {
        return fTmsaccbillsMapper.selectFTmsaccbillsMapList(fTmsaccbills);
    }

    /**
     * 批量删除财务主
     *
     * @param ids 需要删除的财务主ID
     * @return 结果
     */
    @Override
    public int deleteFTmsaccbillsByIds(Long[] ids) {
        return fTmsaccbillsMapper.deleteFTmsaccbillsByIds(ids);
    }

    /**
     * 删除财务主信息
     *
     * @param id 财务主ID
     * @return 结果
     */
    @Override
    public int deleteFTmsaccbillsById(Long id) {
        return fTmsaccbillsMapper.deleteFTmsaccbillsById(id);
    }

    @Override
    public List<Map<String, Object>> fTmsaccbillsList(FTmsaccbillsFees fTmsaccbillsFees, String billsType) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        if (billsType.equals("SFDZ")) {
            mapList = fTmsaccbillsMapper.fTmsaccbillsListAccamount(fTmsaccbillsFees);
        } else {
            mapList = fTmsaccbillsMapper.fTmsaccbillsList(fTmsaccbillsFees);
        }
        return mapList;
    }

    @Override
    @Transactional
    public AjaxResult insertTFeeTFeeDo(String tfee, String tfeeDo, LoginUser loginUser, String fBilltype) {
        Long fPid = null;
        Map<String, Object> map = new HashMap<>();
        FTmsaccbills fTmsaccbills = JSONArray.parseObject(tfee, FTmsaccbills.class);
        if (StringUtils.isNull(fTmsaccbills.getId())) {
            // 如果是新数据
            fTmsaccbills.setCreateBy(loginUser.getUser().getUserName());
            fTmsaccbills.setCreateTime(new Date());
            // 业务编码
            BillnoDel billnoDel = new BillnoDel();
            billnoDel.setBillType(fBilltype);
            List<BillnoDel> billnoDels = billnoDelMapper.selectBillnoDelList(billnoDel);
            if (StringUtils.isNotEmpty(billnoDels)) {
                // 如果有数据在删除列表
                billnoDelMapper.deleteBillnoDelById(billnoDels.get(0).getId());
                fTmsaccbills.setfBillno(billnoDels.get(0).getBillNo());
            } else {
                // 生成流水号
                Date time = new Date();
                String billNo = billnoSerialServiceImpl.getBillNo(fBilltype, time);
                fTmsaccbills.setfBillno(billNo);
            }
            fTmsaccbills.setfBillstatus(2L);
            fTmsaccbills.setfBilltype(fBilltype);
            fTmsaccbills.setfDeptid(SecurityUtils.getLoginUser().getUser().getDeptId());
            fTmsaccbillsMapper.insertFTmsaccbills(fTmsaccbills);
            fPid = fTmsaccbills.getId();
        } else {
            fPid = fTmsaccbills.getId();
            fTmsaccbills.setUpdateTime(new Date());
            fTmsaccbills.setUpdateBy(loginUser.getUser().getUserName());
            fTmsaccbillsMapper.updateFTmsaccbills(fTmsaccbills);
        }
        // 删除从表
        fTmsaccbillsitemsMapper.deleteByFPid(fPid);
        // 本次对账金额合计
        BigDecimal amt = new BigDecimal(0);
        // 应对账金额合计
        BigDecimal amtDr = new BigDecimal(0);
        //  财务从表
        if (StringUtils.isNotNull(tfeeDo)) {
            JSONArray jsonDrArray = JSONArray.parseArray(tfeeDo);
            List<FTmsaccbillsitems> tFeeDoList = JSONObject.parseArray(jsonDrArray.toJSONString(), FTmsaccbillsitems.class);
            for (FTmsaccbillsitems tFeeDo : tFeeDoList) {
                amt = amt.add(tFeeDo.getFAmt());
                amtDr = amtDr.add(tFeeDo.getFAmtdr());
                tFeeDo.setFPid(fPid);
                tFeeDo.setFStatus("2");
                tFeeDo.setCreateTime(new Date());
                tFeeDo.setCreateBy(loginUser.getUser().getUserName());
                fTmsaccbillsitemsMapper.insertFTmsaccbillsitems(tFeeDo);
            }
        }
        fTmsaccbills.setfAmtcr(amt);
        fTmsaccbills.setfAmtdr(amtDr);
        fTmsaccbillsMapper.updateFTmsaccbills(fTmsaccbills);
        map.put("tFee", fTmsaccbillsMapper.selectFTmsaccbillsById(fPid));
        return AjaxResult.success("成功", map);
    }

    @Override
    public AjaxResult queryRemove(Long fId) {
        FTmsaccbills tFee = fTmsaccbillsMapper.selectFTmsaccbillsById(fId);
        FTmsaccbillsitems tFeeDo = new FTmsaccbillsitems();
        tFeeDo.setFSrcid(tFee.getId());
        List<FTmsaccbillsitems> tFeeDoList = fTmsaccbillsitemsMapper.selectFTmsaccbillsitemsList(tFeeDo);
        if (StringUtils.isNull(tFee)) {
            return AjaxResult.success("0");
        } else if (StringUtils.isNotNull(tFee) && StringUtils.isEmpty(tFeeDoList)) {
            return AjaxResult.success("1");
        } else {
            return AjaxResult.success("2");
        }
    }

    /**
     *  费用确认
     * @param tfee
     * @param tfeeDo
     * @param fBilltype
     * @return
     */
    @Override
    @Transactional
    public AjaxResult confirm(String tfee, String tfeeDo, String fBilltype) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        FTmsaccbills fTmsaccbills = JSONArray.parseObject(tfee, FTmsaccbills.class);
        if (StringUtils.isNotNull(fTmsaccbills.getfBillstatus()) && fTmsaccbills.getfBillstatus() == 6) {
            return AjaxResult.success();
        }
        fTmsaccbills.setfBillstatus(4L);
        if (StringUtils.isNull(fTmsaccbills.getId())) {
            // 如果是新数据
            // 业务编码
            BillnoDel billnoDel = new BillnoDel();
            billnoDel.setBillType(fBilltype);
            List<BillnoDel> billnoDels = billnoDelMapper.selectBillnoDelList(billnoDel);
            if (StringUtils.isNotEmpty(billnoDels)) {
                // 如果有数据在删除列表
                billnoDelMapper.deleteBillnoDelById(billnoDels.get(0).getId());
                fTmsaccbills.setfBillno(billnoDels.get(0).getBillNo());
            } else {
                // 生成流水号
                Date time = new Date();
                String billNo = billnoSerialServiceImpl.getBillNo(fBilltype, time);
                fTmsaccbills.setfBillno(billNo);
            }
            fTmsaccbills.setfBilltype(fBilltype);
            fTmsaccbills.setCreateTime(new Date());
            fTmsaccbills.setfDeptid(user.getDeptId());
            fTmsaccbills.setCreateBy(user.getUserName());
            fTmsaccbillsMapper.insertFTmsaccbills(fTmsaccbills);
        } else {
            fTmsaccbills.setUpdateBy(user.getUserName());
            fTmsaccbills.setUpdateTime(new Date());
            fTmsaccbillsMapper.updateFTmsaccbills(fTmsaccbills);
        }
        // 删除从表
        fTmsaccbillsitemsMapper.deleteByFPid(fTmsaccbills.getId());
        //  财务从表
        JSONArray jsonDrArray = JSONArray.parseArray(tfeeDo);
        List<FTmsaccbillsitems> tFeeDoList = JSONObject.parseArray(jsonDrArray.toJSONString(), FTmsaccbillsitems.class);
        // 本次对账金额合计
        BigDecimal amt = new BigDecimal(0);
        // 应对账金额合计
        BigDecimal amtDr = new BigDecimal(0);
        for (FTmsaccbillsitems tFeeDo : tFeeDoList) {
            amt = amt.add(tFeeDo.getFAmt());
            amtDr = amtDr.add(tFeeDo.getFAmtdr());
            tFeeDo.setCreateTime(new Date());
            tFeeDo.setFPid(fTmsaccbills.getId());
            tFeeDo.setCreateBy(user.getUserName());
            fTmsaccbillsitemsMapper.insertFTmsaccbillsitems(tFeeDo);
            // 跟新费用明细
            int m = updateBillsFees(fTmsaccbills.getId(), tFeeDo, fBilltype);
            if (m == 0) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error("更新费用明细失败");
            }
        }
        fTmsaccbills.setfAmtcr(amt);
        fTmsaccbills.setfAmtdr(amtDr);
        fTmsaccbillsMapper.updateFTmsaccbills(fTmsaccbills);
        AjaxResult ajaxResult = tfeeFollow(fTmsaccbills.getId(), 6L);
        String code = ajaxResult.get("code").toString();
        if ("500".equals(code)) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return ajaxResult;
    }

    @Transactional
    public int updateBillsFees(Long fid, FTmsaccbillsitems tFeeDo, String billsType) {
        // 查询从表数据
        FTmsaccbills tFee = fTmsaccbillsMapper.selectFTmsaccbillsById(fid);
        if ("SFDZ".equals(billsType)) {
            billsType = "DZ";
        } else if ("JSFF".equals(billsType) || "JSSF".equals(billsType)) {
            billsType = "DC";
        }
        Map<String, Object> map = new HashMap<>();
        map.put("tFee", tFee);
        map.put("tFeeDo", tFeeDo);
        map.put("billType", billsType);
        return ftmsorderbillsfeesMapper.updateFTmsorderbillsfee(map);
    }

    @Transactional
    public AjaxResult tfeeFollow(Long fPid, long fettle) {
        if (StringUtils.isNull(fPid)) {
            return AjaxResult.error("财务更新状态未找到主表信息，请与管理员联系");
        }
        FTmsaccbills tFee = new FTmsaccbills();
        tFee.setId(fPid);
        tFee.setfBillstatus(fettle);
        tFee.setPostDate(new Date());
        fTmsaccbillsMapper.updateFTmsaccbills(tFee);
        fTmsaccbillsitemsMapper.tfeeDoFollowUpdate(fPid, fettle);
        return AjaxResult.success();
    }
}
