package com.ycsoft.business.service.impl;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ycsoft.beans.config.TPayType;
import com.ycsoft.beans.core.acct.CAcct;
import com.ycsoft.beans.core.acct.CAcctAcctitemActive;
import com.ycsoft.beans.core.acct.CAcctAcctitemChange;
import com.ycsoft.beans.core.cust.CCust;
import com.ycsoft.beans.core.fee.CFeeAcct;
import com.ycsoft.beans.core.prod.CProdOrder;
import com.ycsoft.beans.core.prod.CProdOrderDto;
import com.ycsoft.beans.core.prod.CProdOrderFee;
import com.ycsoft.beans.core.prod.CProdOrderFeeOut;
import com.ycsoft.beans.core.prod.CProdOrderFollowPay;
import com.ycsoft.beans.core.prod.CancelUserDto;
import com.ycsoft.beans.core.user.CUser;
import com.ycsoft.beans.prod.PPackageProd;
import com.ycsoft.beans.prod.PProd;
import com.ycsoft.beans.prod.PProdTariff;
import com.ycsoft.beans.prod.PProdTariffDisct;
import com.ycsoft.beans.prod.PSpkg;
import com.ycsoft.business.component.core.OrderComponent;
import com.ycsoft.business.dao.config.TPayTypeDao;
import com.ycsoft.business.dao.core.cust.CCustDao;
import com.ycsoft.business.dao.core.prod.CProdOrderDao;
import com.ycsoft.business.dao.core.prod.CProdOrderFeeDao;
import com.ycsoft.business.dao.core.user.CUserDao;
import com.ycsoft.business.dao.prod.PPackageProdDao;
import com.ycsoft.business.dao.prod.PProdDao;
import com.ycsoft.business.dao.prod.PProdTariffDao;
import com.ycsoft.business.dao.prod.PProdTariffDisctDao;
import com.ycsoft.business.dao.prod.PSpkgDao;
import com.ycsoft.business.dto.core.acct.PayDto;
import com.ycsoft.business.dto.core.fee.BusiFeeDto;
import com.ycsoft.business.dto.core.prod.OrderProd;
import com.ycsoft.business.dto.core.prod.OrderProdEdit;
import com.ycsoft.business.dto.core.prod.OrderProdPanel;
import com.ycsoft.business.dto.core.prod.PackageGroupPanel;
import com.ycsoft.business.dto.core.prod.PackageGroupUser;
import com.ycsoft.business.service.IOrderService;
import com.ycsoft.commons.constants.BusiCmdConstants;
import com.ycsoft.commons.constants.BusiCodeConstants;
import com.ycsoft.commons.constants.StatusConstants;
import com.ycsoft.commons.constants.SystemConstants;
import com.ycsoft.commons.exception.ComponentException;
import com.ycsoft.commons.exception.ErrorCode;
import com.ycsoft.commons.exception.ServicesException;
import com.ycsoft.commons.helper.CollectionHelper;
import com.ycsoft.commons.helper.DateHelper;
import com.ycsoft.commons.helper.JsonHelper;
import com.ycsoft.commons.helper.LoggerHelper;
import com.ycsoft.commons.helper.StringHelper;
import com.ycsoft.daos.core.JDBCException;
import com.ycsoft.daos.helper.BeanHelper;
@Service
public class OrderService extends BaseBusiService implements IOrderService{
@Autowired
private PProdDao pProdDao;
@Autowired
private PProdTariffDao pProdTariffDao;
@Autowired
private PProdTariffDisctDao pProdTariffDisctDao;
@Autowired
private PPackageProdDao pPackageProdDao;
@Autowired
private CProdOrderDao cProdOrderDao;
@Autowired
private OrderComponent orderComponent;
@Autowired
private CCustDao cCustDao;
@Autowired
private CUserDao cUserDao;
@Autowired
private CProdOrderFeeDao cProdOrderFeeDao;
@Autowired
private TPayTypeDao tPayTypeDao;
@Autowired
private PSpkgDao pSpkgDao;
/**
* 查询订单修改需要初始化数据
* 未支付的,宽带和套餐可以改产品,资费,订购期限,套餐终端选择
* 已支付的,只有协议套餐能修改
* 先实现未支付的修改
* @param orderSn
* @throws Exception
*/
public OrderProdEdit queryOrderToEdit(String orderSn) throws Exception{
if(StringHelper.isEmpty(orderSn)){
throw new ServicesException(ErrorCode.ParamIsNull);
}
CProdOrderDto order=cProdOrderDao.queryCProdOrderDtoByKey(orderSn);
if(order==null){
throw new ServicesException(ErrorCode.ParamIsNull);
}
if(order.getIs_pay().equals(SystemConstants.BOOLEAN_TRUE)
&&!order.getProd_type().equals(SystemConstants.PROD_TYPE_SPKG)){
//已支付的,只有协议套餐能修改
throw new ServicesException(ErrorCode.OrderEditNoProd);
}
OrderProdEdit edit=orderComponent.createOrderEdit(order);
//提取可用的产品和资费列表
orderComponent.queryOrderableEdit(custComponent.queryCustById(order.getCust_id()), order.getOrder_sn(), edit);
//如果当前产品不可用,则装入当前产品和资费
orderEditSetCurrentProdTariff(edit,order);
return edit;
}
/**
* 如果当前产品资费、折扣不可用,则装入当前产品和资费、折扣
* @param edit
* @param order
* @throws Exception
*/
private void orderEditSetCurrentProdTariff(OrderProdEdit edit,CProdOrderDto order) throws Exception{
Map<String,PProd> prodMap=CollectionHelper.converToMapSingle(edit.getProdList(), "prod_id");
if(!prodMap.containsKey(edit.getProd_id())){
prodMap.put(edit.getProd_id(), pProdDao.findByKey(edit.getProd_id()));
edit.getTariffMap().put(edit.getProd_id(), new ArrayList<PProdTariffDisct>());
}
Map<String,PProdTariffDisct> tariffDisctMap=CollectionHelper.converToMapSingle(edit.getTariffMap().get(edit.getProd_id()), "tariff_id");
if(!tariffDisctMap.containsKey(edit.getTariff_id())){
PProdTariff pt=pProdTariffDao.findByKey(order.getTariff_id());
PProdTariffDisct tariff=new PProdTariffDisct();
tariff.setTariff_id(pt.getTariff_id());
tariff.setBilling_cycle(pt.getBilling_cycle());
tariff.setDisct_rent(pt.getRent());
tariff.setDisct_name(pt.getTariff_name());
tariff.setBilling_type(pt.getBilling_type());
if(StringHelper.isNotEmpty(order.getDisct_id())){
PProdTariffDisct disct=pProdTariffDisctDao.findByKey(order.getDisct_id());
tariff.setTariff_id(disct.getTariff_id()+"_"+disct.getDisct_id());
tariff.setBilling_cycle(disct.getBilling_cycle());
tariff.setDisct_rent(disct.getDisct_rent());
tariff.setDisct_name(disct.getDisct_name());
}
edit.getTariffMap().get(edit.getProd_id()).add(tariff);
}
}
/**
* 订单修改功能
* 差额只能使用现金来退款或补收(减少处理难度)
* 新的订单金额不能小于转移支付金额
* 可以修改差额,修改到期日
* 已支付的订单不能退款
* 未支付的订单可以退款
* 套餐 不搞转移支付了,如果还存在被覆盖的独立子产品(可以使用超级退订更正,超级退订可以修改退任意金额)
* @throws Exception
*/
public void saveOrderEdit(OrderProd orderProd) throws Exception{
String cust_id=this.getBusiParam().getCust().getCust_id();
doneCodeComponent.lockCust(cust_id);
CProdOrderDto order=checkOrderEditParam(cust_id,orderProd);
Integer done_code=doneCodeComponent.gDoneCode();
// 客户套餐自动选终端处理,因为前台先不提供客户套餐用户变更功能,如果套餐变更了产品,自动更新用户对应的套餐内容
if(order.getProd_type().equals(SystemConstants.PROD_TYPE_CUSTPKG)
&&!order.getProd_id().equals(orderProd.getProd_id())){
this.editCustOrderAutoSelectUser(orderProd);
}
//记录异动
CProdOrder editOrder=orderComponent.createCProdOrder(orderProd, null, null, null, null);
if(StringHelper.isNotEmpty(this.getBusiParam().getRemark())){
order.setRemark(this.getBusiParam().getRemark());
}
editOrder.setOrder_fee(order.getOrder_fee()+orderProd.getPay_fee());
orderComponent.saveOrderEditChange(order, editOrder,done_code);
//处理费用
if(orderProd.getPay_fee()!=0){
CCust cust=custComponent.queryCustById(cust_id);
//插入CFEE记录
String feeSn=feeComponent.saveOrderEdittoCFee(order, orderProd.getPay_fee(), cust, done_code, this.getBusiParam().getBusiCode());
orderComponent.saveOrderEditFee(order, orderProd.getPay_fee(), feeSn, done_code);
//记录未支付业务
doneCodeComponent.saveDoneCodeUnPay(cust_id, done_code, this.getOptr().getOptr_id());
}
//更新订单,返回有变化的订单信息,套餐会重新处理子产品
List<CProdOrder> orderChangeList=orderComponent.saveOrderEditBean(order, done_code, orderProd);
//移动订单接续,套餐子产品先排,然后排非套餐子产品,使用生效时间排
Map<String,CUser> userMap=userComponent.queryUserMap(cust_id);
orderComponent.moveOrderByCancelOrder(orderChangeList, userMap, done_code);
//处理授权
this.authProdNoPackage(orderChangeList, userMap, done_code);
getBusiParam().setOperateObj("OrderSn:"+editOrder.getOrder_sn());
this.saveAllPublic(done_code, this.getBusiParam());
}
/**
* 订单修改,客户套餐自动选择终端
* @throws Exception
*/
private void editCustOrderAutoSelectUser(OrderProd orderProd) throws Exception{
List<PPackageProd> newPakProds= pPackageProdDao.queryPackProdById(orderProd.getProd_id());
if(newPakProds.size()!= orderProd.getGroupSelected().size()){
throw new ServicesException(ErrorCode.OrderDatePackageConfig);
}
for(PackageGroupUser pgu: orderProd.getGroupSelected()){
PPackageProd oldPakProd=pPackageProdDao.findByKey(pgu.getPackage_group_id());
if(oldPakProd==null){
throw new ServicesException(ErrorCode.OrderDatePackageConfig);
}
PPackageProd selectPakProd=null;//使用套餐终端适用条件去匹配,应该匹配到唯一一条配置
for(PPackageProd newPakProd:newPakProds){
if(newPakProd.getUser_type().equals(oldPakProd.getUser_type())){
if(StringHelper.isEmpty(newPakProd.getTerminal_type())
&&StringHelper.isEmpty(oldPakProd.getTerminal_type())){
if(selectPakProd!=null){//找到多个对应配置错误
throw new ServicesException(ErrorCode.OrderDatePackageConfig);
}
selectPakProd=newPakProd;
}else if(StringHelper.isNotEmpty(newPakProd.getTerminal_type())
&&newPakProd.getTerminal_type().equals(oldPakProd.getTerminal_type())){
if(selectPakProd!=null){//找到多个对应配置错误
throw new ServicesException(ErrorCode.OrderDatePackageConfig);
}
selectPakProd=newPakProd;
}
}
}
if(selectPakProd==null){//找不到对应配置
throw new ServicesException(ErrorCode.OrderDatePackageConfig);
}
pgu.setPackage_group_id(selectPakProd.getPackage_group_id());
}
}
private CProdOrderDto checkOrderEditParam(String cust_id,OrderProd orderProd) throws Exception{
if(StringHelper.isEmpty(cust_id)||orderProd==null||StringHelper.isEmpty(orderProd.getLast_order_sn())){
throw new ServicesException(ErrorCode.ParamIsNull);
}
CProdOrderDto order=cProdOrderDao.queryCProdOrderDtoByKey(orderProd.getLast_order_sn());
if(order==null){
throw new ServicesException(ErrorCode.OrderNotExists);
}
if(StringHelper.isNotEmpty(order.getPackage_sn())){
throw new ServicesException(ErrorCode.OrderEditIsPakDetail);
}
if(!cust_id.equals(orderProd.getCust_id())||
!cust_id.equals(order.getCust_id())){
throw new ServicesException(ErrorCode.CustDataException);
}
// if(!order.getStatus().equals(StatusConstants.ACTIVE)&&!order.getStatus().equals(StatusConstants.INSTALL)){
// throw new ServicesException(ErrorCode.OrderStatusException);
// }
if(order.getStatus().equals(StatusConstants.ACTIVE)&&order.getExp_date().before(DateHelper.today())){
throw new ServicesException(ErrorCode.ProdIsInvalid);//正常状态的订单 但是已过期
}
if(!order.getProd_type().equals(SystemConstants.PROD_TYPE_BASE)){//套餐的情况,有用户
if(StringHelper.isNotEmpty(orderProd.getUser_id())){
throw new ServicesException(ErrorCode.OrderPackageHasSingleUserParam);
}
}else if(!order.getUser_id().equals(orderProd.getUser_id())){//单产品的情况,用户不一致
throw new ServicesException(ErrorCode.OrderDateLastOrderNotUser);
}
//未支付的订单才可以修改
if(orderProd.getPay_fee()<0&&!order.getIs_pay().equals(SystemConstants.BOOLEAN_FALSE)){
throw new ServicesException(ErrorCode.OrderEditOnlyUnPay);
}
//开始计费日校检,开始计费日不能变化
if(order.getEff_date().getTime() != orderProd.getEff_date().getTime()){
throw new ServicesException(ErrorCode.OrderDateEffDateError);
}
//结束计费日,必须大于等于开始计费日
if(orderProd.getExp_date().before(orderProd.getEff_date())){
throw new ServicesException(ErrorCode.OrderDateExpDateError);
}
//支付类型判断,退款只能现金方式
if(orderProd.getPay_fee()<0&&orderProd.getOrder_fee_type()!=null&&!orderProd.getOrder_fee_type().equals(SystemConstants.ORDER_FEE_TYPE_CFEE)){
throw new ServicesException(ErrorCode.OrderDateException);
}
String[] tmpTariff=orderProd.getTariff_id().split("_");
PProdTariff tariff=pProdTariffDao.findByKey(tmpTariff[0]);
if(orderProd.getTransfer_fee()==null){
orderProd.setTransfer_fee(0);
}
//新订单金额
int new_order_fee=order.getOrder_fee()+orderProd.getPay_fee();
if(new_order_fee<0){//订单费用不能小于0
throw new ComponentException(ErrorCode.OrderDateFeeError);
}
int oldTransFee=0;
for(CProdOrderFee orderFee: cProdOrderFeeDao.queryByOrderSn(order.getOrder_sn())){
if(orderFee.getInput_type().equals(SystemConstants.ORDER_FEE_TYPE_TRANSFEE)){
oldTransFee=oldTransFee+orderFee.getFee();
}
}
//新的订单金额不能小于(原始转移支付金额)
if(new_order_fee<oldTransFee){
throw new ComponentException(ErrorCode.OrderDateFeeError);
}
/**订购月数和结束日 校检 结束日是否等于 开始日+订购月数,不再强制验证订单修改的到期日是否准确
if(tariff.getBilling_type().equals(SystemConstants.BILLING_TYPE_DAY)){
Date checkExpDate= DateHelper.addDate(orderProd.getEff_date(), Math.round(orderProd.getOrder_months()*30)-1);
if(!checkExpDate.equals(orderProd.getExp_date())){
throw new ServicesException(ErrorCode.OrderDateExpDateError);
}
}else if(tariff.getBilling_type().equals(SystemConstants.BILLING_TYPE_MONTH)){
//先加整月,然后加天
Date checkExpDate=DateHelper.getNextMonthPreviousDay(orderProd.getEff_date(), orderProd.getOrder_months().intValue());
checkExpDate=DateHelper.addDate(checkExpDate, Math.round((orderProd.getOrder_months().floatValue()-orderProd.getOrder_months().intValue())*30));
if(!checkExpDate.equals(orderProd.getExp_date())){
throw new ServicesException(ErrorCode.OrderDateExpDateError);
}
}**/
return order;
}
/**
* 产品终止退订
* 查询退订\销户可退的订单金额
* 当天订购的订单退全部金额(可能误操作的情况)
* a.普通退订和普通销户:1.包多月产品不可退。
* 2.单月基础产品未过协议期,则协议期外可退,退订业务时重发加授权至协议期。
* 3.单月基础产品已过协议期(或无协议),则可退并终止产品
* 4.单月非基础产品可退并终止产品
* b.高级退订和高级销户可以退钱并终止产品
* c.退款金额按剩余使用月整数计算
* @return
*/
public List<CProdOrderDto> queryCancelFeeByCancelOrder(String busi_code,String cust_id,String order_sn)throws Exception{
//检查是否未支付项目
//List<CDoneCodeUnpay> unPays=doneCodeComponent.queryUnPayList(cust_id);
CProdOrderDto cancelOrder=cProdOrderDao.queryCProdOrderDtoByKey(order_sn);
if(cancelOrder==null||StringHelper.isEmpty(busi_code)){
throw new ServicesException(ErrorCode.ParamIsNull);
}
List<CProdOrderDto> orderList= new ArrayList<>();
orderList.add(cancelOrder);
//碰撞检测
PProd prod=pProdDao.findByKey(cancelOrder.getProd_id());
if(!prod.getProd_type().equals(SystemConstants.PROD_TYPE_BASE)){
//套餐处理
for(CProdOrder checkOrder: cProdOrderDao.queryNotExpPackageOrder(cust_id)){
if(cancelOrder.getExp_date().before(checkOrder.getExp_date())){
throw new ServicesException(ErrorCode.NotCancleTheOrderBefor,checkOrder.getOrder_sn());
}
}
//跟单产品在套餐后续订碰撞
List<CProdOrder> orderAfterPakList=cProdOrderDao.querySingleProdOrderAfterPak(cancelOrder.getOrder_sn());
if(orderAfterPakList!=null&&orderAfterPakList.size()>0){
throw new ServicesException(ErrorCode.NotCancleTheOrderBefor,orderAfterPakList.get(0).getOrder_sn());
}
}else{
//单产品直接碰撞处理
for(CProdOrder checkOrder: cProdOrderDao.queryProdOrderDtoByUserId(cancelOrder.getUser_id())){
if(prod.getServ_id().equals(SystemConstants.PROD_SERV_ID_BAND)||cancelOrder.getProd_id().equals(checkOrder.getProd_id())){
if(cancelOrder.getExp_date().before(checkOrder.getExp_date())){
throw new ServicesException(ErrorCode.NotCancleTheOrderBefor,checkOrder.getOrder_sn());
}
}
}
}
//参数检查
for(CProdOrderDto order:orderList){
//检查能否退订
this.checkOrderCanCancel(cust_id, busi_code, order);
//费用计算
Map<String,Integer> cancelFeeMap=orderComponent.getOrderCancelFee(order,busi_code,DateHelper.today());
order.setBalance_cfee(cancelFeeMap.get(SystemConstants.ORDER_FEE_TYPE_CFEE));
order.setBalance_acct(cancelFeeMap.get(SystemConstants.ORDER_FEE_TYPE_ACCT));
order.setActive_fee(order.getBalance_acct()+order.getBalance_cfee());
}
return orderList;
}
/**
* 用户销户查询该用户的所有产品信息包含退款金额(高级销户,普通销户)
*/
public List<CProdOrderDto> queryLogoffUserProd(String busi_code,String user_id) throws Exception{
List<CUser> userList = this.getBusiParam().getSelectedUsers();
List<CProdOrderDto> orderList=orderComponent.queryLogoffProdOrderDtoByUserId(user_id);
//是否高级权限
boolean isHigh=orderComponent.isHighCancel(busi_code);
//费用
orderComponent.getLogoffOrderFee(orderList, isHigh);
return orderList;
}
public Map<String, Object> queryLogoffUserProdList(String custId, List<String> userIdList) throws Exception {
if(null != userIdList && userIdList.size() == 0){
throw new ServicesException("表格数据为空");
}else if(userIdList.size() > 1000){
throw new ServicesException("请一次性录入小于1000条数据");
}
//过滤重复用户ID
List<String> userIds = new ArrayList<String>();
for(String userId : userIdList){
if(!userIds.contains(userId)){
userIds.add(userId);
}
}
List<CUser> userList = userComponent.queryUserByUserIds(userIds);
if(userList.size() == 0){
throw new ServicesException("无效用户ID");
}
for(CUser user : userList){
if(!user.getCust_id().equals(custId)){
throw new ServicesException("用户【"+user.getUser_id()+"】不在当前客户下!");
}
}
List<CProdOrderDto> prodOrderList = orderComponent.queryLogoffProdOrderDtoByUserIds(userIds);
orderComponent.getLogoffOrderFee(prodOrderList, false);
List<CancelUserDto> cancelList = new ArrayList<CancelUserDto>();
for(CProdOrderDto order : prodOrderList){
CancelUserDto cancelUser = new CancelUserDto();
cancelUser.setUser_id(order.getUser_id());
cancelUser.setProd_name(order.getProd_name());
cancelUser.setActive_fee(order.getActive_fee());
cancelList.add(cancelUser);
}
Map<String, List<CancelUserDto>> orderMap = CollectionHelper.converToMap(cancelList, "user_id");
List<CancelUserDto> returnCancelUserList = new ArrayList<CancelUserDto>();
for(String key : orderMap.keySet()){
List<CancelUserDto> list = orderMap.get(key);
int fee = 0;
for(CancelUserDto order : list){
fee += order.getActive_fee();
}
CancelUserDto cancelUserDto = new CancelUserDto();
cancelUserDto.setUser_id(key);
cancelUserDto.setActive_fee(fee*-1);
returnCancelUserList.add(cancelUserDto);
}
Map<String, List<CancelUserDto>> map = CollectionHelper.converToMap(cancelList, "prod_name");
List<CancelUserDto> showCancelUserList = new ArrayList<CancelUserDto>();
for(String key : map.keySet()){
List<CancelUserDto> list = map.get(key);
int fee = 0;
CancelUserDto cancelUser = new CancelUserDto();
for(CancelUserDto order : list){
fee += order.getActive_fee();
}
cancelUser.setProd_name(key);
cancelUser.setActive_fee(fee);
showCancelUserList.add(cancelUser);
}
Map<String, Object> returnMap = new HashMap<String, Object>();
returnMap.put("showData", showCancelUserList);
returnMap.put("returnData", returnCancelUserList);
returnMap.put("userCount", userList.size());
return returnMap;
}
/**
* 退订产品
* @param
* @throws Exception
*/
public void saveCancelProd(String[] orderSns,Integer cancelFee,Integer refundFee, String acctBalanceType) throws Exception{
String cust_id=this.getBusiParam().getCust().getCust_id();
doneCodeComponent.lockCust(cust_id);
if(StringHelper.isEmpty(acctBalanceType)
||(!acctBalanceType.equals(SystemConstants.ACCT_BALANCE_REFUND)&&
!acctBalanceType.equals(SystemConstants.ACCT_BALANCE_TRANS))){
throw new ServicesException(ErrorCode.ParamIsNull);
}
//退订的费用明细
List<CProdOrderFee> orderFees=new ArrayList<>();
//参数检查,返回退订订单详细信息列表
List<CProdOrderDto> cancelList=checkCancelProdOrderParm(cust_id, orderSns, cancelFee,refundFee,orderFees,acctBalanceType);
Integer done_code=doneCodeComponent.gDoneCode();
List<CProdOrderFeeOut> outList=orderComponent.getOrderFeeOutFromOrderFee(orderFees);
if(refundFee<0&&acctBalanceType.equals(SystemConstants.ACCT_BALANCE_REFUND)){
//现金部分退款
//记录未支付业务
doneCodeComponent.saveDoneCodeUnPay(cust_id, done_code, this.getOptr().getOptr_id());
//保存缴费信息
feeComponent.saveCancelFee(cancelList,outList, this.getBusiParam().getCust(), done_code, this.getBusiParam().getBusiCode());
}
if(acctBalanceType.equals(SystemConstants.ACCT_BALANCE_TRANS)){
//现金部分转账到公用
for(CProdOrderFeeOut orderFee:outList){
if(orderFee.getOutput_type().equals(SystemConstants.ORDER_FEE_TYPE_CFEE)){
orderFee.setOutput_type(SystemConstants.ORDER_FEE_TYPE_ACCT);
}
}
}
if(cancelFee-refundFee!=0||acctBalanceType.equals(SystemConstants.ACCT_BALANCE_TRANS)){
//余额转回公用账目
acctComponent.saveCancelFeeToAcct(outList, cust_id, done_code, this.getBusiParam().getBusiCode());
}
//更新订单费用明细的转出信息
orderComponent.saveOrderFeeOut(outList, done_code);
List<CProdOrder> cancelResultList=new ArrayList<>();
for(CProdOrderDto dto:cancelList){
//执行退订 返回被退订的用户订单清单
cancelResultList.addAll(orderComponent.saveCancelProdOrder(dto, done_code));
}
Map<String,CUser> userMap=new HashMap<>();
//整体移动剩下订单的开始和结束计算日期
orderComponent.moveOrderByCancelOrder(cancelResultList, userMap, done_code);
//退订直接解除授权,不等支付(因为不能取消)
authProdNoPackage(cancelResultList, userMap, done_code);
this.saveAllPublic(done_code, this.getBusiParam());
}
/**
* 退订产品参数检查
* @param busi_code
* @param cust_id
* @param isHigh
* @param orderSns
* @param cancel_fee
* @return
* @throws Exception
*/
private List<CProdOrderDto> checkCancelProdOrderParm(String cust_id,String[] orderSns
,Integer cancel_fee,Integer refund_fee,List<CProdOrderFee> orderFees,String acctBalanceType) throws Exception{
if(StringHelper.isEmpty(cust_id)||cancel_fee==null||orderSns==null||orderSns.length==0){
throw new ServicesException(ErrorCode.ParamIsNull);
}
String busi_code=this.getBusiParam().getBusiCode();
List<CProdOrderDto> cancelList=new ArrayList<>();
//参数检查
//退款总额核对
int fee=0;
//退现金总金额
int cfeeTotal=0;
//相关订单的未支付核对
Map<String,CProdOrderDto> unPayCheckMap=new HashMap<String,CProdOrderDto>();
int needRefundee=refund_fee*-1;//现金退款总额
for(String order_sn:orderSns){
CProdOrderDto order= cProdOrderDao.queryCProdOrderDtoByKey(order_sn);
if(order==null){
throw new ServicesException(ErrorCode.OrderTodayHasCancel);
}
cancelList.add(order);
this.checkOrderCanCancel(cust_id, busi_code, order);
//可退费用计算
List<CProdOrderFee> cancelFeeList=null;
if(busi_code.equals(BusiCodeConstants.PROD_SUPER_TERMINATE)){
//超级退订,退所有钱
cancelFeeList=orderComponent.getOrderCancelAllFeeDetail(order);
}else{
cancelFeeList=orderComponent.getOrderCacelFeeDetail(order,DateHelper.today());
}
for(CProdOrderFee orderFee: cancelFeeList){
fee=fee+orderFee.getOutput_fee();//可退总额计算
if(orderFee.getOutput_type().equals(SystemConstants.ORDER_FEE_TYPE_CFEE)){
cfeeTotal=cfeeTotal+orderFee.getOutput_fee();//可退现金总额计算
}
//计算订单资金的可退现金部分要退多少钱
if(orderFee.getOutput_type().equals(SystemConstants.ORDER_FEE_TYPE_CFEE)){
if(needRefundee==0){
orderFee.setOutput_fee(0);
}
if(needRefundee>orderFee.getOutput_fee()){
needRefundee=needRefundee-orderFee.getOutput_fee();
}else{
orderFee.setOutput_fee(needRefundee);
needRefundee=0;
}
}
}
//设置订单的实际现金退款和 强制转账金额
int outTotalFee=0;
int balanceCfee=0;
for(CProdOrderFee orderFee:cancelFeeList){
outTotalFee=outTotalFee+orderFee.getOutput_fee();
if(orderFee.getOutput_type().equals(SystemConstants.ORDER_FEE_TYPE_CFEE)){
balanceCfee=balanceCfee+orderFee.getOutput_fee();
}
//后面账户扣款异动要使用
orderFee.setRemark(order.getProd_name());
}
order.setActive_fee(outTotalFee);
order.setBalance_cfee(balanceCfee);
order.setBalance_acct(outTotalFee-balanceCfee);
orderFees.addAll(cancelFeeList);
if(!order.getProd_type().equals(SystemConstants.PROD_TYPE_BASE)){
unPayCheckMap.put("PACKAGE", order);
}else if(order.getServ_id().equals(SystemConstants.PROD_SERV_ID_BAND)){
unPayCheckMap.put("BAND", order);
}else {
unPayCheckMap.put("NOBAND", order);
}
}
//金额核对
if(cancel_fee*-1 > fee){
throw new ServicesException(ErrorCode.FeeDateException);
}
if(refund_fee*-1 > cfeeTotal){
throw new ServicesException(ErrorCode.FeeDateException);
}
if(needRefundee!=0){
throw new ServicesException(ErrorCode.FeeDateException);
}
//订单相关的所有订单的未支付判断,判断各类订单的相关所有订单的未支付状态
for(CProdOrderDto checkOrder: unPayCheckMap.values()){
for(CProdOrderDto unPayOrder: orderComponent.queryOrderByCancelOrder(checkOrder)){
if(unPayOrder.getIs_pay().equals(SystemConstants.BOOLEAN_FALSE)){
throw new ServicesException(ErrorCode.NotCancleHasUnPay);
}
}
}
return cancelList;
}
/**
* 判断订单能否退订
* @param cust_id
* @param isHigh
* @param order
* @param prodConfig
* @throws Exception
*/
private void checkOrderCanCancel(String cust_id,String busi_code,CProdOrderDto order) throws Exception{
if(order==null){
throw new ServicesException(ErrorCode.OrderNotExists);
}
if(!cust_id.equals(order.getCust_id())){
throw new ServicesException(ErrorCode.CustDataException);
}
if(StringHelper.isNotEmpty(order.getPackage_sn())){
throw new ServicesException(ErrorCode.NotCancelIsPackageDetail);
}
if(order.getIs_pay().equals(SystemConstants.BOOLEAN_FALSE)){
//未支付判断
throw new ServicesException(ErrorCode.NotCancleHasUnPay);
}
//状态判断
if(!order.getStatus().equals(StatusConstants.ACTIVE)
&&!order.getStatus().equals(StatusConstants.INSTALL)){
throw new ServicesException(ErrorCode.NotCancelStatusException);
}
//时间判断,exp_date 小于今天不能退订
if(order.getExp_date().before(DateHelper.today())){
throw new ServicesException(ErrorCode.NotCancelStatusException);
}
//订购时间=今天或状态是施工中的或高级权限,都可以退订
if(DateHelper.isToday(order.getOrder_time())
||order.getStatus().equals(StatusConstants.INSTALL)
||orderComponent.isHighCancel(busi_code)){
return;
}
//普通退订限制判断
//包多月判断
if(order.getBilling_cycle()>1){
throw new ServicesException(ErrorCode.NotCancelHasMoreBillingCycle);
}
//基础单产品的硬件协议期未到不能终止
if(order.getProd_type().equals(SystemConstants.PROD_TYPE_BASE)
&& order.getIs_base().equals(SystemConstants.BOOLEAN_TRUE)
&&order.getProtocol_date()!=null
&&DateHelper.today().before(order.getProtocol_date())){
throw new ServicesException(ErrorCode.NotCancelUserProtocol);
}
//套餐的情况,判断子产品的硬件协议期
if(!order.getProd_type().equals(SystemConstants.PROD_TYPE_BASE)){
for(CProdOrderDto son: cProdOrderDao.queryProdOrderDtoByPackageSn(order.getOrder_sn())){
if(son.getIs_base().equals(SystemConstants.BOOLEAN_TRUE)
&&son.getProtocol_date()!=null
&&DateHelper.today().before(son.getProtocol_date())){
throw new ServicesException(ErrorCode.NotCancelUserProtocol);
}
}
}
}
@Override
public OrderProdPanel queryOrderableProd(String busiCode,String custId,String userId, String filterOrderSn)
throws Exception{
OrderProdPanel orderProdPanel=orderComponent.queryOrderableProd(busiCode, custId, userId, filterOrderSn);
//IP收费方案处理
if(orderProdPanel.getProdList()!=null&&orderProdPanel.getProdList().size()>0){
complateOrderableProdIpFee(orderProdPanel,custId);
}
return orderProdPanel;
}
/**
* 订购界面的IP收费方案
* @param orderProdPanel
* @throws Exception
*/
private void complateOrderableProdIpFee(OrderProdPanel orderProdPanel,String custId) throws Exception{
Map<String,BusiFeeDto> ipUserFeeMap=feeComponent.queryUserIpAddresFee(custId);
if(ipUserFeeMap.size()==0) return;
if(StringHelper.isNotEmpty(orderProdPanel.getUserId())&&ipUserFeeMap.containsKey(orderProdPanel.getUserId())){
//单用户情况
orderProdPanel.setBusiFee(ipUserFeeMap.get(orderProdPanel.getUserId()));
}else if(StringHelper.isEmpty(orderProdPanel.getUserId())
&&orderProdPanel.getProdList()!=null&&orderProdPanel.getProdList().size()>0){
//套餐情况
List<PPackageProd> pakList=pPackageProdDao.queryPackProdById(orderProdPanel.getProdList().get(0).getProd_id());
if(pakList==null||pakList.size()==0) return;
//随便取一个用户获得IPFee配置
for(BusiFeeDto busiFee: ipUserFeeMap.values()){
orderProdPanel.setBusiFee(busiFee);
break;
}
}
}
@Override
public Map<String,List<CProdOrderDto>> queryCustEffOrder(String custId,String loadType) throws Exception {
List<CProdOrderDto> orderList=null;
if("EFF".equals(loadType)){
//提取有效的订购记录
orderList = cProdOrderDao.queryCustEffOrderDto(custId);
}else if("ALL".equals(loadType)){
//提取未退订的订购记录
orderList=cProdOrderDao.queryCustOrderALLAndHisDto(custId);
}else{
//提取有效的订购记录,如果不存在有效的订购记录 则提取最近一条订购记录
orderList=orderComponent.queryCustEFFAndLastOrder(custId);
}
for (CProdOrderDto order :orderList){
if (StringHelper.isEmpty(order.getUser_id()))
order.setUser_id("CUST");
}
return CollectionHelper.converToMap(orderList, "user_id");
}
/**
* 套餐的用户选择界面加载初始化数据
* @throws Exception
*/
@Override
public PackageGroupPanel queryPackageGroupPanel(String cust_id,
String prod_id, String last_order_sn) throws Exception {
PackageGroupPanel panel=new PackageGroupPanel();
panel.setNeedShow(true);
//装入用户清单
//要装入施工中和正常的状态终端用户
panel.setUserList(userComponent.queryCanSelectByCustId(cust_id));
//有ip费用的用户产品到期日处理
Map<String,BusiFeeDto> ipFeeMap=feeComponent.queryUserIpAddresFee(cust_id);
for(CUser user:panel.getUserList()){
if(ipFeeMap.containsKey(user.getUser_id())){
user.setProd_exp_date(ipFeeMap.get(user.getUser_id()).getLast_prod_exp());
}
}
//装入内容配置信息
fillPackageProdConfig(panel,pPackageProdDao.queryPackProdById(prod_id));
//自动适配选定用户数量
if(!autoSelectUser(panel)){
//自动适配失败,则根据内容组根据上期订购记录选定适配用户
lastOrderSelectUser(prod_id,panel,last_order_sn);
}
return panel;
}
/**
* 补全套餐内容组配置信息
* @param panel
* @param pakprodList
* @throws JDBCException
*/
private void fillPackageProdConfig(PackageGroupPanel panel,List<PPackageProd> pakprodList) throws Exception{
List<PackageGroupUser> groupList=new ArrayList<PackageGroupUser>();
panel.setGroupList(groupList);
for(PPackageProd pakprod: pakprodList){
PackageGroupUser pgu=new PackageGroupUser(pakprod);
groupList.add(pgu);
pgu.setProdList(new ArrayList<PProd>());
for(String prod_id: pakprod.getProd_list().split(",")){
if(StringHelper.isNotEmpty(prod_id)){
PProd prodconfig=pProdDao.findByKey(prod_id);
if(prodconfig==null){
throw new ComponentException(ErrorCode.OrderDatePackageConfig);
}
pgu.getProdList().add(pProdDao.findByKey(prod_id));
}
}
}
}
/**
* 套餐内容组自动适用终端用户
* 如果每个内容组的要求的最大终端用户数量=客户下符合该用户组的用户终端数,则自动匹配成功。
*
* @param panel
*/
private boolean autoSelectUser(PackageGroupPanel panel){
//客户用户组临时存放set
Set<CUser> userSets=new HashSet<CUser>();
userSets.addAll(panel.getUserList());
//生成检查Map
Map<PackageGroupUser,List<String>> checkMap=new HashMap<PackageGroupUser,List<String>>();
for(PackageGroupUser pgu: panel.getGroupList()){
Iterator<CUser> it= userSets.iterator();
while(it.hasNext()){
CUser user=it.next();
if(pgu.getUser_type().equals(user.getUser_type())){
if(StringHelper.isEmpty(pgu.getTerminal_type())
||pgu.getTerminal_type().equals(user.getTerminal_type())){
if(checkMap.get(pgu)==null){
checkMap.put(pgu, new ArrayList<String>());
}
checkMap.get(pgu).add(user.getUser_id());
it.remove();
}
}
}
}
//判断用户数和套餐内容组要求数量是否一致
for(PackageGroupUser pgu: panel.getGroupList()){
//内容组无适用用户,则不能自动适配
if(checkMap.get(pgu)==null){
return false;
}
//内容组最大用户数量和适配用户数量不一致,则不能自动适配
if(checkMap.get(pgu).size()!=pgu.getMax_user_cnt()){
return false;
}
}
//设置自动选中
for(PackageGroupUser pgu: panel.getGroupList()){
pgu.setUserSelectList(checkMap.get(pgu));
}
panel.setNeedShow(false);
return true;
}
/**
* 根据上次订购记录选中适配用户
* @param panel
* @param last_order_sn
* @throws Exception
*/
private void lastOrderSelectUser(String prod_id,PackageGroupPanel panel,String last_order_sn) throws Exception{
//上次订购不存在
if(StringHelper.isEmpty(last_order_sn)) return;
CProdOrder mainorder=cProdOrderDao.findByKey(last_order_sn);
//上次订购不存在或产品不一致
if(mainorder==null){
return;
}else if(prod_id.equals(mainorder.getProd_id())){
this.lastOrderSelectUserByPak(panel, last_order_sn);
}else{
this.lastOrderSelectUserSameProdList( panel, last_order_sn,mainorder.getProd_id());
}
}
/**
* 相同套餐匹配
* @throws JDBCException
*/
private void lastOrderSelectUserByPak(PackageGroupPanel panel,String last_order_sn) throws Exception{
//提取原订购记录的套餐组用户选择情况,且适用现在的套餐产品限制条件
Map<String,Set<String>> selectUsers=new HashMap<String,Set<String>>();
for(CProdOrder order:cProdOrderDao.queryPakDetailOrder(last_order_sn)){
if(StringHelper.isNotEmpty(order.getPackage_group_id())
&&StringHelper.isNotEmpty(order.getUser_id())){
if(selectUsers.get(order.getPackage_group_id())==null){
selectUsers.put(order.getPackage_group_id(), new HashSet<String>());
}
selectUsers.get(order.getPackage_group_id()).add(order.getUser_id());
}
}
//装到新订购的套餐内容组用户选择中
Map<String,CUser> userMap=CollectionHelper.converToMapSingle(panel.getUserList(), "user_id");
for(PackageGroupUser pgu: panel.getGroupList()){
Set<String> userSet=selectUsers.get(pgu.getPackage_group_id());
if(userSet!=null){
pgu.setUserSelectList(new ArrayList<String>());
for(String user_id:userSet){
if(pgu.getUserSelectList().size()>=pgu.getMax_user_cnt()){
break;
}
CUser user=userMap.get(user_id);
if(user==null){
continue;
}
if(!user.getUser_type().equals(pgu.getUser_type())){
continue;
}
if(StringHelper.isNotEmpty(pgu.getTerminal_type())
&&!pgu.getTerminal_type().equals(user.getTerminal_type())){
continue;
}
pgu.getUserSelectList().add(user_id);
}
}
}
}
/**
* 不同套餐,使用相同内容匹配
* @throws Exception
*/
private void lastOrderSelectUserSameProdList(PackageGroupPanel panel,String last_order_sn,String last_pak_id) throws Exception{
Map<String,PPackageProd> lastPakProdMap=CollectionHelper.converToMapSingle(
pPackageProdDao.queryPackProdById(last_pak_id), "package_group_id");
//提取原订购记录的套餐组用户选择情况,且适用现在的套餐产品限制条件
//Map<prod_list,Set<user_id>> selectUsers 宽带内容组填BAND
Map<String,Set<String>> selectUsers=new HashMap<String,Set<String>>();
for(CProdOrder order:cProdOrderDao.queryPakDetailOrder(last_order_sn)){
if(StringHelper.isNotEmpty(order.getPackage_group_id())
&&StringHelper.isNotEmpty(order.getUser_id())
&&lastPakProdMap.containsKey(order.getPackage_group_id())){
PPackageProd pakProd=lastPakProdMap.get(order.getPackage_group_id());
String key=pakProd.getProd_list();
if(pakProd.getUser_type().equals(SystemConstants.USER_TYPE_BAND)){
key=SystemConstants.USER_TYPE_BAND;
}
if(selectUsers.get(key)==null){
selectUsers.put(key, new HashSet<String>());
}
selectUsers.get(key).add(order.getUser_id());
}
}
//装到新订购的套餐内容组用户选择中
Map<String,CUser> userMap=CollectionHelper.converToMapSingle(panel.getUserList(), "user_id");
for(PackageGroupUser pgu: panel.getGroupList()){
String key=pgu.getProd_list();
if(pgu.getUser_type().equals(SystemConstants.USER_TYPE_BAND)){
key=SystemConstants.USER_TYPE_BAND;
}
Set<String> userSet=selectUsers.get(key);
if(userSet!=null&&userSet.size()>0){
pgu.setUserSelectList(new ArrayList<String>());
for(String user_id:userSet){
if(pgu.getUserSelectList().size()>=pgu.getMax_user_cnt()){
break;
}
CUser user=userMap.get(user_id);
if(user==null){
continue;
}
if(!user.getUser_type().equals(pgu.getUser_type())){
continue;
}
if(StringHelper.isNotEmpty(pgu.getTerminal_type())
&&!pgu.getTerminal_type().equals(user.getTerminal_type())){
continue;
}
pgu.getUserSelectList().add(user_id);
}
userSet.removeAll(pgu.getUserSelectList());
}
}
}
/**
* 查询转移支付的被退的订单清单
* 要排除未支付的订单
* @throws Exception
*/
@Override
public List<CProdOrderDto> queryTransferFee(OrderProd orderProd,String busi_code) throws Exception{
List<CProdOrderDto> list=new ArrayList<>();
for(CProdOrder order: orderComponent.queryTransCancelOrderList(orderProd, busi_code)){
if(order.getIs_pay().equals(SystemConstants.BOOLEAN_TRUE)){
CProdOrderDto dto=cProdOrderDao.queryCProdOrderDtoByKey(order.getOrder_sn());
//计算可退余额
dto.setActive_fee(orderComponent.getTransCancelFee(orderProd.getEff_date(), order));
list.add(dto);
}else{
throw new ServicesException(ErrorCode.OrderTransUnPayPleaseCancel,order.getOrder_sn());
}
}
return list;
}
/**
* 查询ott_mobile升级的转移支付金额
* @param cancelList
* @return
* @throws Exception
*/
public Integer queryOttMobileUpdateTransferFee(List<CProdOrderDto> cancelList) throws Exception{
Date eff_date=DateHelper.today();
int translate_fee=0;
for(CProdOrderDto order: cancelList){
if(order.getIs_pay().equals(SystemConstants.BOOLEAN_TRUE)){
//计算可退余额
translate_fee=translate_fee+orderComponent.getTransCancelFee(eff_date, order);
}else{
throw new ServicesException(ErrorCode.OrderTransUnPayPleaseCancel,order.getOrder_sn());
}
}
return translate_fee;
}
/**
* 订单的业务参数
*/
public static String getOrderProdRemark(OrderProd orderProd,String busi_code,String order_sn,Integer done_code) throws Exception{
Map<String,Object> busiMap=new HashMap<>();
busiMap.put("busi_code", busi_code);
busiMap.put("cust_id", orderProd.getCust_id());
busiMap.put("user_id", orderProd.getUser_id());
busiMap.put("prod_id", orderProd.getProd_id());
busiMap.put("tariff_id", orderProd.getTariff_id());
busiMap.put("last_order_sn", orderProd.getLast_order_sn());
busiMap.put("order_months", orderProd.getOrder_months());
busiMap.put("pay_fee", orderProd.getPay_fee());
busiMap.put("transfer_fee", orderProd.getTransfer_fee());
busiMap.put("eff_date", orderProd.getEff_date());
busiMap.put("exp_date", orderProd.getExp_date());
busiMap.put("order_fee_type", orderProd.getOrder_fee_type());
busiMap.put("order_sn", order_sn);
busiMap.put("done_code", done_code);
if(orderProd.getGroupSelected()!=null&&orderProd.getGroupSelected().size()>0){
for(PackageGroupUser pgu: orderProd.getGroupSelected()){
//package_group_id userSelectList
Map<String,Object> groupDetailMap=new HashMap<>();
busiMap.put(StringHelper.append("package_group_id_",pgu.getPackage_group_id()),groupDetailMap);
if(pgu.getUserSelectList()!=null){
groupDetailMap.put("cnt", pgu.getUserSelectList().size());
if(pgu.getUserSelectList().size()<=5){
groupDetailMap.put("userIds", pgu.getUserSelectList());
}else{
groupDetailMap.put("userIds", StringHelper.append("[",
"pgu.getUserSelectList().get(0)",
",...,",
pgu.getUserSelectList().get(pgu.getUserSelectList().size()-1),
"]"));
}
}else{
groupDetailMap.put("cnt", "null");
}
}
}
return JsonHelper.fromObject(busiMap);
}
public List<String> saveOrderProdList(String busi_code,OrderProd...orderProds) throws Exception{
//锁定未支付业务,防止同一个客户被多个操作员操作订购产品
if(orderProds==null||orderProds.length==0){
throw new ServicesException(ErrorCode.OrderNotExists);
}
String cust_id=null;
for(OrderProd orderProd:orderProds){
if(cust_id!=null&&!cust_id.equals(orderProd.getCust_id())){
throw new ServicesException(ErrorCode.CustDataException);
}else if(cust_id==null){
cust_id=orderProd.getCust_id();
}
}
if(!this.getBusiParam().getCust().getCust_id().equals(cust_id)){
throw new ServicesException(ErrorCode.CustDataException);
}
doneCodeComponent.lockCust(cust_id);
Integer doneCode = doneCodeComponent.gDoneCode();
List<String> prodSns=new ArrayList<>();
//保存未支付业务信息
for(OrderProd orderProd:orderProds){
if(orderProd.getPay_fee()>0&&!SystemConstants.ORDER_FEE_TYPE_ACCT.equals(orderProd.getOrder_fee_type())){
doneCodeComponent.saveDoneCodeUnPay(cust_id, doneCode,getOptr().getOptr_id());
break;
}
}
for(OrderProd orderProd:orderProds){
prodSns.add(this.saveOrderProd(orderProd,busi_code,doneCode));
}
//业务流水
this.saveAllPublic(doneCode, getBusiParam());
return prodSns;
}
/**
* ott_mobile产品升级
* @param orderProd
* @param cancleOrderList
* @param busi_code
* @param doneCode
* @throws Exception
*/
public void saveOttMobileUpdateProd(OrderProd orderProd,List<CProdOrderDto> cancleOrderList,String busi_code,Integer doneCode)throws Exception{
PProd prodConfig=pProdDao.findByKey(orderProd.getProd_id());
//参数检查
checkOrderProdParam(orderProd,prodConfig,busi_code);
String optr_id=this.getBusiParam().getOptr().getOptr_id();
CCust cust=cCustDao.findByKey(orderProd.getCust_id());
CProdOrder cProdOrder=orderComponent.createCProdOrder(orderProd, doneCode, optr_id, cust.getArea_id(), cust.getCounty_id());
//产品状态设置
cProdOrder.setStatus(StatusConstants.ACTIVE);
//业务是否需要支付判断
cProdOrder.setIs_pay(SystemConstants.BOOLEAN_TRUE);
//保存订购记录
orderComponent.saveCProdOrderByOttMobileUpgrade(cProdOrder, orderProd, cancleOrderList);
}
/**
* 保存订购记录
* @return
* @throws Exception
*/
protected String saveOrderProd(OrderProd orderProd,String busi_code,Integer doneCode) throws Exception{
PProd prodConfig=pProdDao.findByKey(orderProd.getProd_id());
//参数检查
CProdOrder lastOrder=checkOrderProdParam(orderProd,prodConfig,busi_code);
String optr_id=this.getBusiParam().getOptr().getOptr_id();
CCust cust=cCustDao.findByKey(orderProd.getCust_id());
//主订购记录bean生成
CProdOrder cProdOrder=orderComponent.createCProdOrder(orderProd, doneCode, optr_id, cust.getArea_id(), cust.getCounty_id());
//产品状态设置
cProdOrder.setStatus(orderComponent.getNewOrderProdStatus(lastOrder,orderProd));
//业务是否需要支付判断
cProdOrder.setIs_pay(orderProd.getPay_fee()>0&&!SystemConstants.ORDER_FEE_TYPE_ACCT.equals(orderProd.getOrder_fee_type())
?SystemConstants.BOOLEAN_FALSE:SystemConstants.BOOLEAN_TRUE);
cProdOrder.setRemark(this.getBusiParam().getRemark());
if(LoggerHelper.isDebugEnabled(this.getClass())){//日志记录业务参数,可能核对需要使用
LoggerHelper.debug(this.getClass(), getOrderProdRemark(orderProd,busi_code,cProdOrder.getOrder_sn(),doneCode));
}
//保存订购记录
orderComponent.saveCProdOrder(cProdOrder,orderProd,busi_code);
//已支付且订单状态是正常的要发加授权指令
this.atvProd(cProdOrder, prodConfig,doneCode);
//费用信息
if(orderProd.getPay_fee()>0){
if(!SystemConstants.ORDER_FEE_TYPE_ACCT.equals(orderProd.getOrder_fee_type())){
//缴费支付
this.saveCFee(cProdOrder,orderProd.getPay_fee(),cust,doneCode,busi_code);
}else{
//账户支付
this.savePayOrderByAcct(cProdOrder,prodConfig,orderProd.getPay_fee(),doneCode,busi_code);
}
}
return cProdOrder.getOrder_sn();
}
/**
* 使用账户支付订单金额
* @throws Exception
*/
private void savePayOrderByAcct(CProdOrder cProdorder,PProd prodConfig,Integer payFee,Integer doneCode,String busiCode) throws Exception{
CAcct acct=acctComponent.queryCustAcctByCustId(cProdorder.getCust_id());
//扣款
List<CAcctAcctitemChange> changeList=
acctComponent.saveAcctDebitFee(acct.getCust_id(), acct.getAcct_id(), SystemConstants.ACCTITEM_PUBLIC_ID,
SystemConstants.ACCT_CHANGE_PAY, payFee*-1, busiCode, doneCode, false,prodConfig.getProd_name());
//订单资金明细
List<CProdOrderFee> orderFees=new ArrayList<>();
for(CAcctAcctitemChange change:changeList){
CProdOrderFee orderFee=new CProdOrderFee();
orderFees.add(orderFee);
orderFee.setOrder_fee_sn(cProdOrderFeeDao.findSequence().toString());
orderFee.setDone_code(doneCode);
orderFee.setOrder_sn(cProdorder.getOrder_sn());
orderFee.setInput_type(SystemConstants.ORDER_FEE_TYPE_ACCT);
orderFee.setInput_sn(change.getAcct_change_sn());
orderFee.setInput_fee(change.getChange_fee()*-1);
orderFee.setFee(change.getChange_fee()*-1);
orderFee.setFee_type(change.getFee_type());
orderFee.setCreate_time(new Date());
orderFee.setCounty_id(cProdorder.getCounty_id());
orderFee.setArea_id(cProdorder.getArea_id());
}
cProdOrderFeeDao.save(orderFees.toArray(new CProdOrderFee[orderFees.size()]));
}
/**
* 激活产品
* 已支付要发加授权指令,且服务渠道非移动端的(移动端是直接授权)
* @param cProdOrder
* @param prodConfig
* @throws JDBCException
*/
private void atvProd(CProdOrder cProdOrder,PProd prodConfig,Integer doneCode) throws Exception{
if(SystemConstants.SERVICE_CHANNEL_MOBILE.equals(this.getBusiParam().getService_channel())){
//移动渠道走直接授权,不通过异步指令授权
return;
}
if(prodConfig.getProd_type().equals(SystemConstants.PROD_TYPE_BASE)){
List<CProdOrder> list=new ArrayList<>();
list.add(cProdOrder);
authComponent.sendAuth(cUserDao.findByKey(cProdOrder.getUser_id()), list, BusiCmdConstants.ACCTIVATE_PROD, doneCode);
}else{
//套餐的授权
Map<String,CUser> userMap=CollectionHelper.converToMapSingle(cUserDao.queryUserByCustId(cProdOrder.getCust_id()), "user_id");
Map<CUser,List<CProdOrder>> atvMap=new HashMap<>();
for(CProdOrder order: cProdOrderDao.queryPakDetailOrder(cProdOrder.getOrder_sn())){
CUser user=userMap.get(order.getUser_id());
if(user==null){
throw new ServicesException(ErrorCode.OrderDateException,order.getOrder_sn());
}
List<CProdOrder> list=atvMap.get(user);
if(list==null){
list=new ArrayList<>();
atvMap.put(user, list);
}
list.add(order);
}
for(CUser user:atvMap.keySet()){
authComponent.sendAuth(user, atvMap.get(user), BusiCmdConstants.ACCTIVATE_PROD, doneCode);
}
}
}
/**
* 保存订单收费费用信息
* @param orderProd
* @throws InvocationTargetException
* @throws IllegalAccessException
*/
private void saveCFee(CProdOrder cProdorder,Integer payFee,CCust cust,Integer doneCode,String busi_code) throws Exception{
PayDto pay=new PayDto();
BeanHelper.copyProperties(pay, cProdorder);
pay.setProd_sn(cProdorder.getOrder_sn());
pay.setAcctitem_id(cProdorder.getProd_id());
pay.setBegin_date(DateHelper.dateToStr(cProdorder.getEff_date()));
pay.setInvalid_date(DateHelper.dateToStr(cProdorder.getExp_date()));
pay.setPresent_fee(0);
pay.setFee(payFee);
CFeeAcct feeAcct=feeComponent.saveAcctFee(cust.getCust_id(), cust.getAddr_id(), pay, doneCode, busi_code, StatusConstants.UNPAY);
//插入订单费用明细
CProdOrderFee inputOrderFee=new CProdOrderFee();
inputOrderFee.setOrder_fee_sn(cProdOrderFeeDao.findSequence().toString());
inputOrderFee.setOrder_sn(cProdorder.getOrder_sn());
inputOrderFee.setDone_code(doneCode);
inputOrderFee.setInput_type(SystemConstants.ORDER_FEE_TYPE_CFEE);
inputOrderFee.setInput_sn(feeAcct.getFee_sn());
inputOrderFee.setInput_fee(payFee);
inputOrderFee.setFee(payFee);
inputOrderFee.setFee_type( StatusConstants.UNPAY);
inputOrderFee.setCounty_id(cProdorder.getCounty_id());
inputOrderFee.setArea_id(cProdorder.getArea_id());
inputOrderFee.setCreate_time(new Date());
cProdOrderFeeDao.save(inputOrderFee);
}
/**
* 保存业务的未支付信息
* @param orderProd
* @return
* @throws JDBCException
* @throws Exception
private boolean saveDoneCodeUnPay(String custId,Integer payFee,Integer done_code,String optr_id) throws Exception{
List<CDoneCodeUnpay> unPayList = doneCodeComponent.queryUnPayList(custId);
if(unPayList.size()==0&&payFee==0){
//没有未支付的业务,且当前新订单不需要支付,则该笔订单业务设置为已支付
return true;
}else{
doneCodeComponent.saveDoneCodeUnPay(custId, done_code,optr_id);
return false;
}
}
*/
/**
* 检查保存产品订购的参数
* @param orderProd
* @param busi_code
* @return
* @throws Exception
*/
private CProdOrder checkOrderProdParam(OrderProd orderProd,PProd prodConfig,String busi_code) throws Exception{
PProd prod=prodConfig;
if(!prod.getProd_type().equals(SystemConstants.PROD_TYPE_BASE)){
if(StringHelper.isNotEmpty(orderProd.getUser_id())){
throw new ServicesException(ErrorCode.OrderPackageHasSingleUserParam);
}
}
CProdOrder lastOrder=null;
//user_id数据校验
if(StringHelper.isNotEmpty(orderProd.getLast_order_sn())){
lastOrder=cProdOrderDao.findByKey(orderProd.getLast_order_sn());
if(lastOrder==null){
throw new ServicesException(ErrorCode.OrderDateLastOrderIsLost);
}
if(!lastOrder.getCust_id().equals(orderProd.getCust_id())){
throw new ServicesException(ErrorCode.OrderDateLastOrderNotCust);
}
if(StringHelper.isNotEmpty(lastOrder.getUser_id())){
if(StringHelper.isEmpty(orderProd.getUser_id())){
orderProd.setUser_id(lastOrder.getUser_id());
}
if(!lastOrder.getUser_id().equals(orderProd.getUser_id())){
throw new ServicesException(ErrorCode.OrderDateLastOrderNotUser);
}
CUser user=cUserDao.findByKey(orderProd.getUser_id());
if(user==null){
throw new ServicesException(ErrorCode.OrderDateUserNotCust,orderProd.getUser_id());
}
if(!user.getCust_id().equals(orderProd.getCust_id())){
throw new ServicesException(ErrorCode.OrderDateUserNotCust,orderProd.getUser_id());
}
}
}
//上期订购记录校检,是否最近一条订购记录
if(lastOrder!=null){
List<CProdOrder> lastOrderList=new ArrayList<>();
if(!prod.getProd_type().equals(SystemConstants.PROD_TYPE_BASE)){
//套餐的情况
lastOrderList=cProdOrderDao.queryNotExpPackageOrder(orderProd.getCust_id());
}else if(prod.getServ_id().equals(SystemConstants.PROD_SERV_ID_BAND)){
//单产品宽带的情况
for(CProdOrder order: cProdOrderDao.queryProdOrderDtoByUserId(orderProd.getUser_id())){
lastOrderList.add(order);
}
}else{
//单产品非宽带的情况
for(CProdOrder order: cProdOrderDao.queryProdOrderDtoByUserId(orderProd.getUser_id())){
if(order.getProd_id().equals(orderProd.getProd_id())){
lastOrderList.add(order);
}
}
}
if(lastOrderList==null||lastOrderList.size()==0){
throw new ServicesException(ErrorCode.OrderDateLastOrderIsLost);
}
for(CProdOrder tmpOrder:lastOrderList){
if(tmpOrder.getExp_date().after(lastOrder.getExp_date())){
throw new ServicesException(ErrorCode.OrderDateLastOrderIsLost);
}
}
}
//开始计费日校检
if(StringHelper.isNotEmpty(orderProd.getLast_order_sn())
&&!busi_code.equals(BusiCodeConstants.PROD_UPGRADE)){
//有上期订购记录且非升级的情况,开始计费日是上期计费日+1天
if(!DateHelper.addDate(lastOrder.getExp_date(), 1).equals(orderProd.getEff_date())){
throw new ServicesException(ErrorCode.OrderDateEffDateError);
}
}else{
//没有上期订购记录 或者 升级的情况,开始计费日=今天
if(!DateHelper.isToday(orderProd.getEff_date())){
throw new ServicesException(ErrorCode.OrderDateEffDateError);
}
}
//订购月数校检
String[] tmpTariff=orderProd.getTariff_id().split("_");
int billing_cycle=0;
int rent=0;
PProdTariff tariff=pProdTariffDao.findByKey(tmpTariff[0]);
//验证协议套餐能否适用
if(StringHelper.isNotEmpty(tariff.getSpkg_sn())){
PSpkg spkg = pSpkgDao.querySpkgBySn(tariff.getSpkg_sn());
if(spkg == null){
throw new ServicesException(ErrorCode.SpkgIsError);
}else if(!spkg.getStatus().equals(StatusConstants.CONFIRM)){
throw new ServicesException(ErrorCode.SpkgHasNotCONFIRM);
}else if(!tariff.getSpkg_sn().equals(this.getBusiParam().getCust().getSpkg_sn())){
throw new ServicesException(ErrorCode.SpkgIsNotTrueCust);
}
if(lastOrder!=null){
CProdOrderDto tmp= cProdOrderDao.queryCProdOrderDtoByKey(lastOrder.getOrder_sn());
if(tmp==null){
throw new ServicesException(ErrorCode.ParamIsNull);
}
if(!SystemConstants.PROD_TYPE_SPKG.equals(tmp.getProd_type())){
throw new ServicesException(ErrorCode.SpkgIsPaiChuCustKG);
}
}
}
if(tmpTariff.length==2){
PProdTariffDisct disct= pProdTariffDisctDao.findByKey(tmpTariff[1]);
billing_cycle=disct.getBilling_cycle();
rent=disct.getDisct_rent();
}else{
billing_cycle=tariff.getBilling_cycle();
rent=tariff.getRent();
}
//订购期数(包天=round(order_months*30))
//TODO 这个不足一个周期需要如何修改
int order_cycles=tariff.getBilling_type().equals(SystemConstants.BILLING_TYPE_DAY)?
Math.round(orderProd.getOrder_months()*30):orderProd.getOrder_months().intValue();
//记录资费计费类型和订购周期数(后面要使用)
//orderProd.setBilling_type(tariff.getBilling_type());
//orderProd.setOrder_cycle(order_cycles);
if(orderProd.getOrder_months()==0){
throw new ComponentException(ErrorCode.OrderDateOrderMonthError);
}
//非0资费且普通订购,续订,套餐订购,缴费 验证订购月数,订购金额,截止日期 是否一致
if(rent>0&&(busi_code.equals(BusiCodeConstants.PROD_SINGLE_ORDER)||
busi_code.equals(BusiCodeConstants.PROD_CONTINUE)||
busi_code.equals(BusiCodeConstants.PROD_PACKAGE_ORDER)||
busi_code.equals(BusiCodeConstants.ACCT_PAY))){
//订购月数
if(order_cycles%billing_cycle!=0){
throw new ComponentException(ErrorCode.OrderDateOrderMonthError);
}
//订购金额
if(orderProd.getPay_fee()==0&& (rent*order_cycles/billing_cycle) !=(orderProd.getPay_fee()+orderProd.getTransfer_fee())){
throw new ComponentException(ErrorCode.OrderDateFeeError);
}
//包月 结束计费日=开始计费日+订购月数 -1天。
if(tariff.getBilling_type().equals(SystemConstants.BILLING_TYPE_MONTH)
&& !DateHelper.getNextMonthPreviousDay(orderProd.getEff_date(), order_cycles)
.equals(orderProd.getExp_date())){
throw new ServicesException(ErrorCode.OrderDateExpDateError);
}
//包天 结束计费日=开始计费日+订购天数-1天
if(tariff.getBilling_type().equals(SystemConstants.BILLING_TYPE_DAY)
&& !DateHelper.addDate(orderProd.getEff_date(), order_cycles-1)
.equals(orderProd.getExp_date())){
throw new ServicesException(ErrorCode.OrderDateExpDateError);
}
}
//支付类型判断
if(orderProd.getOrder_fee_type()!=null){
if(!orderProd.getOrder_fee_type().equals(SystemConstants.ORDER_FEE_TYPE_ACCT)
&&!orderProd.getOrder_fee_type().equals(SystemConstants.ORDER_FEE_TYPE_CFEE)){
throw new ServicesException(ErrorCode.OrderDateException);
}
}
return lastOrder;
}
/**
* 缴费界面数据初始化
* 过期产品的问题?怎么搞好?
*/
public List<CProdOrderFollowPay> queryFollowPayOrderDto(String custId) throws Exception{
//doneCodeComponent.checkUnPayOtherLock(custId, this.getOptr().getOptr_id());
List<CProdOrderFollowPay> orderList = orderComponent.queryFollowPayOrderDto(custId);
if(orderList.size()>0){
//ip收费
complateFollowPayIpAddressFee(orderList,custId);
}
return orderList;
}
/**
* 补全缴费节目的IP收费方案
* @param orderList
* @param custId
* @throws Exception
*/
private void complateFollowPayIpAddressFee(List<CProdOrderFollowPay> orderList,String custId) throws Exception{
//IP加挂收费处理
Map<String,BusiFeeDto> ipUserFeeMap=feeComponent.queryUserIpAddresFee(custId);
if(ipUserFeeMap.size()==0) return;
for(CProdOrderFollowPay fp:orderList){
if(StringHelper.isNotEmpty(fp.getUser_id())){
//单产品
if(ipUserFeeMap.containsKey(fp.getUser_id())){
fp.setBusiFee(ipUserFeeMap.get(fp.getUser_id()));
}
}else if(fp.getGroupSelected()!=null&&fp.getGroupSelected().size()>0){
//套餐判断用户选择有
BusiFeeDto busiFee=null;
for(PackageGroupUser pgu: fp.getGroupSelected()){
if(pgu.getUserSelectList()!=null&&pgu.getUserSelectList().size()>0){
for(String userId:pgu.getUserSelectList()){
if(ipUserFeeMap.containsKey(userId)){
BusiFeeDto _selectBusiFee=ipUserFeeMap.get(userId);
if(busiFee==null){
busiFee=_selectBusiFee;
}else{
if(!busiFee.getFee_id().equals(_selectBusiFee.getFee_id())){
throw new ServicesException(ErrorCode.CustUserIpAddressFeeCoinfigError);
}
busiFee.setFee_count(busiFee.getFee_count()+_selectBusiFee.getFee_count());
if(_selectBusiFee.getLast_prod_exp().after(busiFee.getLast_prod_exp())){
busiFee.setLast_prod_exp(_selectBusiFee.getLast_prod_exp());
}
}
}
}
}
}
fp.setBusiFee(busiFee);
}
}
}
public void savePublicRecharge(String pay_type, Integer fee, String receipt_id) throws Exception {
if(fee == null || fee == 0){
throw new ServicesException(ErrorCode.ParamIsNull);
}
CCust cust=this.getBusiParam().getCust();
String custId = cust.getCust_id();
doneCodeComponent.lockCust(custId);
Integer doneCode=doneCodeComponent.gDoneCode();
String busiCode = this.getBusiParam().getBusiCode();
if(fee >0){
if(pay_type.equals(SystemConstants.PAY_TYPE_CASH)){
//记录未支付业务
doneCodeComponent.saveDoneCodeUnPay(custId, doneCode, this.getOptr().getOptr_id());
}
//查询公用账户
CAcct acct=acctComponent.queryCustAcctByCustId(cust.getCust_id());
String acctItemId=SystemConstants.ACCTITEM_PUBLIC_ID;
//保存退款记录
PayDto pay = new PayDto();
pay.setCust_id(custId);
pay.setAcct_id(acct.getAcct_id());
pay.setAcctitem_id(SystemConstants.ACCTITEM_PUBLIC_ID);
pay.setFee(fee);
feeComponent.saveAcctFee(custId, cust.getAddr_id(), pay, doneCode, busiCode, StatusConstants.UNPAY);
//保存缴费信息
TPayType type = tPayTypeDao.findByKey(pay_type);
acctComponent.saveAcctAddFee(custId, acct.getAcct_id(), acctItemId, SystemConstants.ACCT_CHANGE_CFEE, fee, type.getAcct_feetype(), busiCode, doneCode,null);
}
this.saveAllPublic(doneCode, this.getBusiParam());
}
public void savePublicRefund(Integer fee) throws Exception {
if(fee == null || fee == 0){
throw new ServicesException(ErrorCode.ParamIsNull);
}
String custId=this.getBusiParam().getCust().getCust_id();
doneCodeComponent.lockCust(custId);
Integer doneCode=doneCodeComponent.gDoneCode();
//记录未支付业务
doneCodeComponent.saveDoneCodeUnPay(custId, doneCode, this.getOptr().getOptr_id());
CAcct acct = acctComponent.queryCustAcctByCustId(custId);
//保存退款记录
PayDto pay = new PayDto();
pay.setCust_id(custId);
pay.setAcct_id(acct.getAcct_id());
pay.setAcctitem_id(SystemConstants.ACCTITEM_PUBLIC_ID);
pay.setFee(fee*-1);
feeComponent.saveAcctFee(custId,this.getBusiParam().getCust().getAddr_id(), pay, doneCode, this.getBusiParam().getBusiCode(), SystemConstants.PAY_TYPE_UNPAY);
acctComponent.saveAcctDebitFee(custId, acct.getAcct_id(), SystemConstants.ACCTITEM_PUBLIC_ID, SystemConstants.ACCT_CHANGE_REFUND, fee*-1, this.getBusiParam().getBusiCode(), doneCode, true,null);
//检查金额
List<CAcctAcctitemActive> list = acctComponent.queryActiveMinusByCustId(custId);
if(list.size()>0){
throw new ComponentException(ErrorCode.AcctBalanceError);
}
this.saveAllPublic(doneCode, this.getBusiParam());
}
@Override
public void savePayOtherFee() throws Exception {
String custId=this.getBusiParam().getCust().getCust_id();
doneCodeComponent.lockCust(custId);
Integer doneCode=doneCodeComponent.gDoneCode();
this.saveAllPublic(doneCode, this.getBusiParam());
}
}