RationOldBiz.java 17.5 KB
package com.cjs.cms.biz.ration;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cjs.cms.biz.user.FundBiz;
import com.cjs.cms.biz.user.fund.UserFinanceBiz;
import com.cjs.cms.dao.quota.OtcStockRealDao;
import com.cjs.cms.dao.ration.MchPriceDao;
import com.cjs.cms.dao.ration.OtcStockJourDao;
import com.cjs.cms.dao.ration.OtcTrustEECodeDao;
import com.cjs.cms.dao.ration.RationOldConfigDao;
import com.cjs.cms.dao.ration.RationOldQualityDao;
import com.cjs.cms.dao.ration.RationOldRecordDao;
import com.cjs.cms.dao.ration.TrustApplyExtDao;
import com.cjs.cms.dao.user.MemberDao;
import com.cjs.cms.model.pub.ConstInfo;
import com.cjs.cms.model.ration.RationOldConfigInfo;
import com.cjs.cms.model.ration.RationOldQualityInfo;
import com.cjs.cms.model.ration.RationOldRecordInfo;
import com.cjs.cms.model.ration.RationOldUserInfo;
import com.cjs.cms.model.ration.TrustApplyExtInfo;
import com.cjs.cms.util.lang.DateEnum;
import com.cjs.cms.util.lang.DateUtil;
import com.cjs.cms.util.t2.T2Result;
import com.cjs.cms.util.web.ActionUtil;

/**
 * 再托管配售
 * @author tongxiaochuan
 *
 */
@Service
public class RationOldBiz {

    Logger                      log = LogManager.getLogger();
    @Autowired
    private MemberDao           memberDao;
    @Autowired
    private FundBiz             fundBiz;
    @Autowired
    private RationOldRecordDao  rationOldRecordDao;
    @Autowired
    private RationOldConfigDao  rationOldConfigDao;
    @Autowired
    private TrustApplyExtDao    trustApplyExtDao;
    @Autowired
    private RationOldQualityDao rationOldQualityDao;
    @Autowired
    private OtcTrustEECodeDao   otcTrustEECodeDao;
    @Autowired
    private UserFinanceBiz      userFinanceBiz;
    @Autowired
    private StorageBiz          storageBiz;
    @Autowired
    private OtcStockJourDao     otcStockJourDao;
    @Autowired
    private OtcStockRealDao     otcStockRealDao;
    @Autowired
    private MchPriceDao         mchPriceDao;

    /**配售*/
    public Map<String, Object> ration(int id) {
        Map<String, Object> outmap = new HashMap<String, Object>();
        RationOldConfigInfo rationOldConfigInfo = rationOldConfigDao.queryAllById(id);
        try {
            if (rationOldConfigInfo == null) {
                outmap.put("resultCode", "0");
                outmap.put("resultMsg", "配售设置信息不存在");
                return outmap;
            }
            if (!"5".equals(rationOldConfigInfo.getRationStatus())) {
                outmap.put("resultCode", "0");
                outmap.put("resultMsg", "非已分配资格状态的规则不可以进行配售操作");
                return outmap;
            }
            if (new Date().getTime() < rationOldConfigInfo.getConfirmEndDate().getTime()) {
                outmap.put("resultCode", "0");
                outmap.put("resultMsg", "请在买入确认结束时间之后再进行配售操作");
                return outmap;
            }
            Integer aggreeCount = trustApplyExtDao
                .queryAggreeCount(rationOldConfigInfo.getOtcCode());
            if (aggreeCount == null || aggreeCount == 0) {
                outmap.put("resultCode", "0");
                outmap.put("resultMsg", "参与该品种再托管的申请数量为0");
                return outmap;
            }

            List<RationOldQualityInfo> qualityList = rationOldQualityDao
                .queryByConfigId(rationOldConfigInfo.getId());

            //获取配售用户列表
            List<TrustApplyExtInfo> trustApplies = trustApplyExtDao
                .queryAggreeList(rationOldConfigInfo.getOtcCode());

            //验证内置账户余额是否足够
            int trustApplyNum = 0; //托管总数
            int rationOldQualityNum = 0; //同意配售总数
            for (TrustApplyExtInfo trustApplyExtInfo : trustApplies) {
                trustApplyNum += trustApplyExtInfo.getApprovalCount();
            }
            for (RationOldQualityInfo rationOldQualityInfo : qualityList) {
                rationOldQualityNum += rationOldQualityInfo.getRationAmount();
            }
            for (RationOldUserInfo oldUserInfo : rationOldConfigInfo.getUsers()) {
                Map<String, Object> balance = userFinanceBiz.balance(oldUserInfo.getUserId());
                Double enableBalance = Double.parseDouble(balance.get("enable_balance").toString());
                Double needMoney = (trustApplyNum - rationOldQualityNum)
                                   * (oldUserInfo.getPercent() / 100)
                                   * rationOldConfigInfo.getPrice();
                if (needMoney > enableBalance) {
                    outmap.put("resultCode", "0");
                    outmap.put("resultMsg",
                        "内置账户" + oldUserInfo.getUserId() + "余额不足,可用余额:["
                                            + enableBalance.doubleValue() + "],需要:[" + needMoney
                                            + "]");
                    return outmap;
                }
            }

            for (TrustApplyExtInfo trustApplyExtInfo : trustApplies) {
                if (trustApplyExtInfo.getApprovalCount() == 0) {
                    continue;
                }
                rationTrust(rationOldConfigInfo, qualityList, trustApplyExtInfo);
            }

            //配售结果
            if (rationOldRecordDao.queryRecordCount(id, "0") > 0) {
                return this.rationResult(4, "配售部分成功", rationOldConfigInfo);
            }
            return this.rationResult(3, "配售成功", rationOldConfigInfo);
        } catch (Exception e) {
            log.error("配售失败", e);
            return this.rationResult(4, e.getMessage(), rationOldConfigInfo);
        }
    }

    /**单个在托管申请订单配售*/
    private void rationTrust(RationOldConfigInfo rationOldConfigInfo,
                             List<RationOldQualityInfo> qualityList, TrustApplyExtInfo trustApply) {
        try {
            List<T2Result> results = new ArrayList<T2Result>();
            int rationTotal = trustApply.getApprovalCount();
            double money;
            String sellOtcAccount = memberDao.queryOtcAccount(trustApply.getFundAccount());
            RationOldRecordInfo record = new RationOldRecordInfo();
            record.setRationOldConfigId(rationOldConfigInfo.getId());
            record.setSellUserId(trustApply.getFundAccount());
            record.setSellOtcAccount(sellOtcAccount);
            record.setApplyNo(trustApply.getApplyNo());
            record.setPreInStatus("0");
            record.setApprovalCount(rationTotal);
            record.setRegistration("0");
            record.setRationStatus("1");
            record.setCreateBy(ActionUtil.getUser().getTruename());

            if (!"1".equals(trustApply.getAggreeStatus())) {
                record.setRationStatus("0");
                record.setRemark("该托管单状态不是同意配售");
                rationOldRecordDao.insert(record);
                return;
            }
            if (trustApply.getApprovalCount() <= 0) {
                record.setRationStatus("0");
                record.setRemark("该托管单鉴定通过数量为0");
                rationOldRecordDao.insert(record);
                return;
            }
            if (!"4".equals(trustApply.getApplyType()) && !"5".equals(trustApply.getApplyType())) {
                record.setRationStatus("0");
                record.setRemark("该托管单鉴定状态为" + trustApply.getApplyType());
                rationOldRecordDao.insert(record);
                return;
            }

            List<RationOldQualityInfo> removeList = new ArrayList<RationOldQualityInfo>();
            //配售
            for (RationOldQualityInfo qualityInfo : qualityList) {
                List<RationOldRecordInfo> existList = rationOldRecordDao.queryReordByCondition(
                    qualityInfo.getRationOldConfigId(), qualityInfo.getUserId());
                if (existList.size() > 0) {
                    int rationNum = rationOldRecordDao.queryStockAmount(
                        qualityInfo.getRationOldConfigId(), qualityInfo.getUserId());
                    int rationAmount = rationOldQualityDao.queryRationAmount(
                        qualityInfo.getRationOldConfigId(), qualityInfo.getUserId());
                    if (rationNum >= rationAmount) {
                        removeList.add(qualityInfo);
                        continue;
                    } else {
                        qualityInfo.setRationAmount(rationAmount - rationNum);
                    }
                }

                //资金解冻
                T2Result result = fundBiz.freezeRecord(qualityInfo.getUserId(),
                    rationOldConfigInfo.getConfirmStartDate(),
                    rationOldConfigInfo.getConfirmEndDate());
                String remark = "配售产品:" + rationOldConfigInfo.getOtcCode();
                for (Map<String, Object> map : result.getData()) {
                    //解冻
                    if (remark.equals(map.get("remark"))) {
                        fundBiz.unfreezeFund(qualityInfo.getId().toString(),
                            ConstInfo.Fund.OLD_RATION, qualityInfo.getUserId(),
                            map.get("serial_no").toString(), DateUtil.parseDate(
                                map.get("curr_date").toString(), DateEnum.UNSIGNED_DATE));
                    }
                }

                if (rationTotal == 0) {
                    break;
                }

                record.setBuyUserId(qualityInfo.getUserId());
                record.setBuyOtcAccount(memberDao.queryOtcAccount(qualityInfo.getUserId()));
                record.setRationOldQualityId(qualityInfo.getId());

                //判断用户可用资金是否足够
                //                Map<String, Object> balance = userFinanceBiz.balance(qualityInfo.getUserId());
                //                if (Double.parseDouble(
                //                    balance.get("enable_balance").toString()) < rationOldConfigInfo.getPrice()
                //                                                                * qualityInfo.getRationAmount()) {
                //                    record.setStockAmount(0);
                //                    record.setFund(0.00);
                //                    record.setRationStatus("0");
                //                    record.setRemark("可用资金不足");
                //                    rationOldRecordDao.insert(record);
                //                    continue;
                //                }

                if (rationTotal >= qualityInfo.getRationAmount()) {
                    money = rationOldConfigInfo.getPrice() * qualityInfo.getRationAmount();
                    record.setStockAmount(qualityInfo.getRationAmount());
                    record.setFund(money);
                    rationOldRecordDao.insert(record);
                    if (money > 0.0) {
                        results = userFinanceBiz.pay(record.getId().toString(),
                            ConstInfo.Fund.OLD_RATION, qualityInfo.getUserId(),
                            trustApply.getFundAccount(), money, ConstInfo.Fund.OLD_RATION_REMARK);
                        this.payResult(results, record);
                        rationOldRecordDao.updateById(record);
                        rationTotal -= qualityInfo.getRationAmount();
                        removeList.add(qualityInfo);
                    }
                } else {
                    money = rationTotal * rationOldConfigInfo.getPrice();
                    record.setFund(money);
                    record.setStockAmount(rationTotal);
                    rationOldRecordDao.insert(record);

                    results = userFinanceBiz.pay(record.getId().toString(),
                        ConstInfo.Fund.OLD_RATION, qualityInfo.getUserId(),
                        trustApply.getFundAccount(), money, ConstInfo.Fund.OLD_RATION_REMARK);
                    this.payResult(results, record);
                    rationOldRecordDao.updateById(record);
                    qualityInfo.setRationAmount(qualityInfo.getRationAmount() - rationTotal);
                    rationTotal = 0;
                }
            }

            //将已经处理的配售资格记录从list中移除
            for (RationOldQualityInfo oldQualityInfo : removeList) {
                qualityList.remove(oldQualityInfo);
            }

            //配售给内部账户
            if (qualityList.size() == 0) {
                int rationNum = 0;
                int rationSum = 0;
                for (int i = 0; i < rationOldConfigInfo.getUsers().size(); i++) {
                    RationOldUserInfo oldUserInfo = rationOldConfigInfo.getUsers().get(i);
                    if (i == rationOldConfigInfo.getUsers().size() - 1) {
                        rationNum = rationTotal - rationSum;
                    } else {
                        rationNum = (int) (rationTotal * oldUserInfo.getPercent() / 100);
                        rationSum += rationNum;
                    }
                    record.setBuyUserId(oldUserInfo.getUserId());
                    record.setBuyOtcAccount(memberDao.queryOtcAccount(oldUserInfo.getUserId()));
                    record.setRationOldQualityId(0);
                    money = rationOldConfigInfo.getPrice() * rationNum;
                    record.setStockAmount(rationNum);
                    record.setFund(money);
                    rationOldRecordDao.insert(record);
                    if (money > 0.0) {
                        results = userFinanceBiz.pay(record.getId().toString(),
                            ConstInfo.Fund.OLD_RATION, oldUserInfo.getUserId(),
                            trustApply.getFundAccount(), money, ConstInfo.Fund.OLD_RATION_REMARK);
                        this.payResult(results, record);
                        rationOldRecordDao.updateById(record);
                    }
                }
            }

            //入库
            if ("5".equals(trustApply.getApplyType())) {
                record.setPreInStatus("1");
            }
            if ("4".equals(trustApply.getApplyType())) {
                T2Result result = storageBiz.storage(trustApply.getApplyNo());
                if (result.getCode() == 0) {
                    record.setPreInStatus("1");
                } else {
                    record.setRationStatus("0");
                }
            }
            rationOldRecordDao.updateByApplyNo(record);
            trustApplyExtDao.updateAggreeStatus(trustApply.getApplyNo(), "2");
        } catch (Exception e) {
            trustApplyExtDao.updateAggreeStatus(trustApply.getApplyNo(), "0");
            log.error("配售出错:" + trustApply.getApplyNo(), e);
        }
    }

    /**处理支付结果*/
    private RationOldRecordInfo payResult(List<T2Result> results, RationOldRecordInfo record) {
        if (results.size() == 1) {
            record.setRemark(results.get(0).toString());
            record.setRationStatus("0");
            trustApplyExtDao.updateAggreeStatus(record.getApplyNo(), "0");
        } else {
            StringBuilder sb = new StringBuilder();
            for (T2Result result : results) {
                sb.append(result.toString()).append("|");
            }
            record.setRemark(sb.toString());
        }
        return record;
    }

    /**返回配售结果信息*/
    private Map<String, Object> rationResult(Integer code, String message,
                                             RationOldConfigInfo configInfo) {
        Map<String, Object> outmap = new HashMap<String, Object>();
        outmap.put("resultCode", code);
        outmap.put("resultMsg", message);
        configInfo.setRationStatus(code.toString());
        configInfo.setRationResult(message);
        rationOldConfigDao.update(configInfo);
        return outmap;
    }

    /**
     * 修改成本价*/
    @Transactional
    public Map<String, Object> changeCostPrice(Integer id) {
        Map<String, Object> outmap = new HashMap<String, Object>();
        RationOldConfigInfo configInfo = rationOldConfigDao.queryById(id);
        Map<String, Object> priceMap = mchPriceDao.queryLastPrice(configInfo.getOtcCode());
        List<Map<String, Object>> query = rationOldRecordDao.queryForCostPrice(id);
        for (Map<String, Object> map : query) {
            map.put("businessFlag", "35034");
            int existFlag = otcStockJourDao.queryRecordExist(map);
            if (existFlag > 0) {
                Double lastPrice = 0.00;
                if (Double.parseDouble(priceMap.get("LAST_PRICE").toString()) == 0.00) {
                    lastPrice = Double.parseDouble(priceMap.get("MCLOSE_PRICE").toString());
                } else {
                    lastPrice = Double.parseDouble(priceMap.get("LAST_PRICE").toString());
                }
                Double mixBalance = (lastPrice - Double.parseDouble(map.get("price").toString()))
                                    * Integer.parseInt(map.get("stockAmount").toString());
                map.put("mixBalance", mixBalance);
                otcStockRealDao.updateSumBuyBalance(map);
                rationOldRecordDao
                    .updateCostPriceStatus(Integer.parseInt(map.get("id").toString()));
            }
        }
        outmap.put("resultCode", "1");
        outmap.put("resultMsg", "修改完毕");
        return outmap;
    }
}