package com.kingdee.eas.assetmamage.operationmanage.leasebiz.app;

import org.apache.log4j.Logger;
import javax.ejb.*;
import java.rmi.RemoteException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.amazon.redshift.shaded.joda.time.DateTime;
import com.amazon.redshift.shaded.joda.time.Months;
import com.amazon.redshift.shaded.joda.time.format.DateTimeFormat;
import com.amazon.redshift.shaded.joda.time.format.DateTimeFormatter;
import com.kingdee.bos.*;
import com.kingdee.bos.util.BOSObjectType;
import com.kingdee.bos.metadata.IMetaDataPK;
import com.kingdee.bos.metadata.rule.RuleExecutor;
import com.kingdee.bos.metadata.MetaDataPK;
//import com.kingdee.bos.metadata.entity.EntityViewInfo;
import com.kingdee.bos.framework.ejb.AbstractEntityControllerBean;
import com.kingdee.bos.framework.ejb.AbstractBizControllerBean;
//import com.kingdee.bos.dao.IObjectPK;
import com.kingdee.bos.dao.IObjectValue;
import com.kingdee.bos.dao.IObjectCollection;
import com.kingdee.bos.service.ServiceContext;
import com.kingdee.bos.service.IServiceContext;

import com.kingdee.eas.framework.app.CoreBillBaseControllerBean;
import com.kingdee.eas.framework.SystemEnum;
import com.kingdee.bos.dao.IObjectPK;
import com.kingdee.bos.dao.ormapping.ObjectUuidPK;
import com.kingdee.eas.framework.ObjectBaseCollection;
import java.lang.String;
import java.math.BigDecimal;

import com.kingdee.eas.framework.CoreBillBaseCollection;
import com.kingdee.eas.assetmamage.operationmanage.accountbill.ReceiveBillEntryCollection;
import com.kingdee.eas.assetmamage.operationmanage.accountbill.ReceiveBillEntryInfo;
import com.kingdee.eas.assetmamage.operationmanage.accountbill.ReceiveBillFactory;
import com.kingdee.eas.assetmamage.operationmanage.accountbill.ReceiveBillInfo;
import com.kingdee.eas.assetmamage.operationmanage.basedata.RentBasisEnum;
import com.kingdee.eas.assetmamage.operationmanage.basedata.RoomFactory;
import com.kingdee.eas.assetmamage.operationmanage.basedata.RoomInfo;
import com.kingdee.eas.assetmamage.operationmanage.basedata.contractType;
import com.kingdee.eas.assetmamage.operationmanage.basedata.oldOrNew;
import com.kingdee.eas.assetmamage.operationmanage.leasebiz.RentContractContractLTECollection;
import com.kingdee.eas.assetmamage.operationmanage.leasebiz.RentContractContractLTEInfo;
import com.kingdee.eas.assetmamage.operationmanage.leasebiz.RentContractInfo;
import com.kingdee.eas.assetmamage.operationmanage.leasebiz.RentContractCollection;
import com.kingdee.eas.base.permission.UserInfo;
import com.kingdee.bos.metadata.entity.EntityViewInfo;
import com.kingdee.eas.framework.CoreBaseCollection;
import com.kingdee.eas.framework.CoreBaseInfo;
import com.kingdee.bos.util.BOSUuid;
import com.kingdee.eas.common.EASBizException;
import com.kingdee.eas.common.SysContextConstant;
import com.kingdee.bos.metadata.entity.SelectorItemCollection;

public class RentContractControllerBean extends AbstractRentContractControllerBean
{
private static Logger logger =
Logger.getLogger("com.kingdee.eas.assetmamage.operationmanage.leasebiz.app.RentContractControllerBean");


@Override
protected void _passAudit(Context ctx, IObjectPK pk, IObjectValue model)
throws EASBizException, BOSException {
// 设置已审核
model.put("statu", "2");
model.put("auditTime", new Date() );
// 设置审核人
UserInfo currentUser = (UserInfo) ctx.get(SysContextConstant.USERINFO);
model.put("auditor", currentUser.getId().toString());
try {
//super.update(ctx, new ObjectUuidPK(info.getId()), info);
SelectorItemCollection selector = new SelectorItemCollection();
selector.add("statu");
selector.add("auditTime");
selector.add("auditor");
updatePartial(ctx, (CoreBaseInfo) model , selector);
} catch (EASBizException e) {
e.printStackTrace();
}

super._passAudit(ctx, pk, model);
}



@Override
protected void _unpassAudit(Context ctx, IObjectPK pk, IObjectValue model)
throws EASBizException, BOSException {
// 设置未审核
model.put("statu", "0");
model.put("auditTime",null );
// 设置审核人
model.put("auditor", null);
try {
SelectorItemCollection selector = new SelectorItemCollection();
selector.add("statu");
selector.add("auditTime");
selector.add("auditor");
updatePartial(ctx, (CoreBaseInfo) model , selector);
} catch (EASBizException e) {
e.printStackTrace();
}
super._unpassAudit(ctx, pk, model);
}




/**
* 合同提交后 根据缴费周期 产生合同缴费账单,
* @throws BOSException
* @throws EASBizException
*/

public void createReceiveBill(Context ctx, IObjectValue model) throws EASBizException, BOSException{
RentContractInfo rentContractInfo=(RentContractInfo)model;
RentBasisEnum rentBasis = rentContractInfo.getRentBasis();//记租类型 0 =建筑面积 ; 1=室内面积
int payCycle = rentContractInfo.getPayCycle(); //缴费周期 (拍租默认6个月 ,招商默认3个月)
oldOrNew oldOrNew = rentContractInfo.getOldOrNew();// 新旧合同 ( 0:新合同 1:旧合同 )
contractType contractType = rentContractInfo.getContractType();// 合同类型
Date contractStartDate = rentContractInfo.getContractStartDate();//租赁开始日期
Date contractEndDate = rentContractInfo.getContractEndDate();//租赁结束日期
String roomsIds = rentContractInfo.getRoomsIds(); // 选择的房源ids
String roomNames=" ";
BigDecimal sumRentArea = BigDecimal.ZERO; //租赁合同 出租总面积
BigDecimal sumRent = BigDecimal.ZERO; //租赁合同 出租总金额
BigDecimal averagePrice = BigDecimal.ZERO; //租赁合同 租赁单价


RentContractContractLTECollection contractLTE = rentContractInfo.getContractLTE();
for (int i = 0; i <contractLTE.size(); i++) {
RentContractContractLTEInfo rentContractContractLTEInfo = contractLTE.get(i);
RoomInfo roomInfo = RoomFactory.getLocalInstance(ctx).getRoomInfo( new ObjectUuidPK(rentContractContractLTEInfo.getRoom().getId().toString()));
roomNames=" "+roomInfo.getName()+" ";
sumRentArea=sumRentArea.add(rentContractContractLTEInfo.getRentArea());//租期条款中的 出租面积
BigDecimal unitPrice = rentContractContractLTEInfo.getUnitPrice();//租期条款中的租金单价
BigDecimal money = unitPrice.multiply(rentContractContractLTEInfo.getRentArea() );// 房源单价*出租面积
sumRent.add(money);
}
//合同总房源的平均单价
averagePrice=sumRent.divide(sumRentArea,BigDecimal.ROUND_HALF_UP,2); // 平均单价=出租总金额/出租总面积
//合同缴费账单
ReceiveBillInfo receiveBillInfo = new ReceiveBillInfo();
receiveBillInfo.setBizDate(new Date());//业务日期
receiveBillInfo.setRentContract(rentContractInfo);//租赁合同
receiveBillInfo.setBeginDate(contractStartDate);//租赁开始日期
receiveBillInfo.setEndDate(contractEndDate);//租赁结束日期
receiveBillInfo.setRooms(roomNames);//房源
receiveBillInfo.setCustomer(rentContractInfo.getCustomer());//承租方
ReceiveBillEntryCollection receiveBillEntry = receiveBillInfo.getEntrys();

if(contractType.getValue().equals("1")){//招商 (新合同自然账期 , 旧合同循环账期, 旧合同在生成合同缴费账单的时候,要判断初始化时导入的合同缴费账单到第几期了。顺延生成下期)
if(oldOrNew.getValue().equals("1")){//新合同
//招商-新合同-自然账期


}else{
//招商-旧合同-循环账期

}
}

if(contractType.getValue().equals("2")){//拍租 (拍租 都是循环账期)
if(oldOrNew.getValue().equals("1")){
//拍租 -新合同-循环账期

}else{
//拍租 -旧合同-循环账期

}
}
}




/**
* 招商 新 生成账期 自然月份
* 租赁合同 租赁开始日期 - 租赁结束日期 除以 循环周期月数 , 返回账期数据
* @throws ParseException
*
*/
public static JSONArray ZsAccountingperiod( Context ctx, RentContractInfo rentContractInfo , Date startDate ,Date contractendDate, int payCycle ) throws ParseException{
int intervalMonths = intervalMonths( startDate, contractendDate ); //得到月份差 (忽略月份后的天数)
int round = Math.round(intervalMonths/payCycle); //租赁期间 间隔月份/循环月 四舍五入获得账期

JSONArray jsonArray = new JSONArray(); //账期集合
SimpleDateFormat simpleDate= new SimpleDateFormat("yyyy-MM-dd");
Date accountEndDate = endDate( startDate , payCycle );
int j=1;
for (int i = 0; i <round; i++) {
JSONObject jsonObject = new JSONObject();
if(i == 0){

}else{
startDate=nextMonthBeginDay( accountEndDate );
}
accountEndDate = endDate( startDate , payCycle );
if(accountEndDate.compareTo(contractendDate)<0){
jsonObject.put("账期", j);
jsonObject.put("开始时间", simpleDate.format(startDate));
jsonObject.put("结束时间", simpleDate.format(accountEndDate));

}else {
// 结算处出的账期 结束日期 >合同租赁日期
jsonObject.put("账期", j);
jsonObject.put("开始时间", simpleDate.format(startDate));
jsonObject.put("结束时间", simpleDate.format(contractendDate));
}
j=j+1;
jsonArray.add(jsonObject);
}


//判断计算出的账期 是否已经到合同租赁到期日 不到 余下的算作一个账期
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject zq = jsonArray.getJSONObject(jsonArray.size()-1);
String accountEndDateStr = zq.get("结束时间").toString();
accountEndDate = simpleDate.parse(accountEndDateStr);
if(accountEndDate.compareTo(contractendDate)<0){
Date nextMonthBeginDay = nextMonthBeginDay( accountEndDate ) ;//返回下个月月初
accountEndDate = endDate( nextMonthBeginDay , payCycle );
JSONObject jsonObject = new JSONObject();
jsonObject.put("账期", j++);
jsonObject.put("开始时间", simpleDate.format(nextMonthBeginDay));
jsonObject.put("结束时间", simpleDate.format(accountEndDate));
jsonArray.add(jsonObject);
}

}


//判断 最后一个账期的结束日期 是否超出 合同租赁结束日期 超出的话,最后一个账期的结束日期为 合同租赁结束日期
JSONObject zq = jsonArray.getJSONObject(jsonArray.size()-1);
String accountEndDateStr = zq.get("结束时间").toString();
accountEndDate = simpleDate.parse(accountEndDateStr);
if(accountEndDate.compareTo(contractendDate)>0) {
JSONObject jsonObject = jsonArray.getJSONObject (jsonArray.size()-1);
jsonObject.put("结束时间", simpleDate.format(contractendDate));
}

//判断 该合同是否是 新合同, 旧合同需要判断 初始化导入的合同已经生成了几期账单,已生成的账期 不在生成
// String oldOrNew = rentContractInfo.getOldOrNew().getValue(); //"0";//alias=新合同 "1";//alias=旧合同
// if(oldOrNew.equals("0")){
// try {
// ReceiveBillInfo receiveBillInfo = ReceiveBillFactory.getLocalInstance(ctx).getReceiveBillInfo(" select * from where rentContract='"+rentContractInfo.getId().toString()+"' ");
// ReceiveBillEntryCollection entrys = receiveBillInfo.getEntrys();
// int size = entrys.size(); //可当做 该合同缴费账单的账期
// for (int i = 0; i < entrys.size(); i++) {
// jsonArray.remove(i);
// }
// } catch (EASBizException e) {
// e.printStackTrace();
// } catch (BOSException e) {
// e.printStackTrace();
// }
// jsonArray=jsonArray;
// return jsonArray;
// }
return jsonArray;
}







/**
* 招商 旧合同 循环月 生成账期 拍租循环月 生成账期
* 租赁合同 租赁开始日期 - 租赁结束日期 除以 循环周期月数 , 返回账期数据
* @throws ParseException
*
*/
public static JSONArray OldAccountingperiod( Date startDate ,Date contractendDate, int payCycle ) throws ParseException{
int intervalMonths = intervalMonths( startDate, contractendDate ); //得到月份差 (忽略月份后的天数)
int round = Math.round(intervalMonths/payCycle); //租赁期间 间隔月份/循环月 四舍五入获得账期

JSONArray jsonArray = new JSONArray(); //账期集合
SimpleDateFormat simpleDate= new SimpleDateFormat("yyyy-MM-dd");
Date accountEndDate =endDateXh( startDate , payCycle );
int j=1;
for (int i = 0; i <round; i++) {
JSONObject jsonObject = new JSONObject();
if(i == 0){

}else{
startDate=DateAddOne( accountEndDate );
}
accountEndDate = endDateXh( startDate , payCycle );
if(accountEndDate.compareTo(contractendDate)<0){
jsonObject.put("账期", j);
jsonObject.put("开始时间", simpleDate.format(startDate));
jsonObject.put("结束时间", simpleDate.format(accountEndDate));

}else {
// 结算处出的账期 结束日期 >合同租赁日期
jsonObject.put("账期", j);
jsonObject.put("开始时间", simpleDate.format(startDate));
jsonObject.put("结束时间", simpleDate.format(contractendDate));
}
j=j+1;
jsonArray.add(jsonObject);
}


//判断计算出的账期 是否已经到合同租赁到期日 不到 余下的算作一个账期
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject zq = jsonArray.getJSONObject(jsonArray.size()-1);
String accountEndDateStr = zq.get("结束时间").toString();
accountEndDate = simpleDate.parse(accountEndDateStr);
if(accountEndDate.compareTo(contractendDate)<0){
Date nextMonthBeginDay = DateAddOne( accountEndDate ) ;//返回下个循环月
accountEndDate = endDateXh( nextMonthBeginDay , payCycle );
JSONObject jsonObject = new JSONObject();
jsonObject.put("账期", j++);
jsonObject.put("开始时间", simpleDate.format(nextMonthBeginDay));
jsonObject.put("结束时间", simpleDate.format(accountEndDate));
jsonArray.add(jsonObject);
}

}


//判断 最后一个账期的结束日期 是否超出 合同租赁结束日期 超出的话,最后一个账期的结束日期为 合同租赁结束日期
JSONObject zq = jsonArray.getJSONObject(jsonArray.size()-1);
String accountEndDateStr = zq.get("结束时间").toString();
accountEndDate = simpleDate.parse(accountEndDateStr);
if(accountEndDate.compareTo(contractendDate)>0) {
JSONObject jsonObject = jsonArray.getJSONObject (jsonArray.size()-1);
jsonObject.put("结束时间", simpleDate.format(contractendDate));
}

//判断 该合同是否是 新合同, 旧合同需要判断 初始化导入的合同已经生成了几期账单,已生成的账期 不在生成
return jsonArray;
}




/**
* 返回 下月月初日期
* @throws ParseException
*/
public static Date DateAddOne ( Date date ) {

Calendar cale = Calendar.getInstance();
cale.setTime(date);
cale.add(Calendar.DATE, 1);
return cale.getTime();
}


/**
* 返回 下月 日期 循环月
* @throws ParseException
*/
public static Date nextMonthBeginDayXh( Date date ) {

Calendar cale = Calendar.getInstance();
cale.setTime(date);
cale.add(Calendar.MONTH, 1);
cale.add(Calendar.DATE, 1);
return cale.getTime();
}





/**
* 开始日期 + 账期月份 循环月
* @throws ParseException
*/
public static Date endDateXh( Date startDate , int payCycle ) {
SimpleDateFormat dataFormat= new SimpleDateFormat("yyyy-MM-dd");
Calendar cal = Calendar.getInstance();
cal.setTime(startDate);
cal.add(Calendar.MONTH, payCycle) ;
cal.add(Calendar.DATE, -1);
Date time = cal.getTime();
return time;
}





/**
* 返回 下月月初日期
* @throws ParseException
*/
public static Date nextMonthBeginDay( Date date ) {

Calendar cale = Calendar.getInstance();
cale.setTime(date);
cale.add(Calendar.MONTH, 1);
cale.set(Calendar.DAY_OF_MONTH, 1);
return cale.getTime();
}




/**
* 开始日期 + 账期月份
* @throws ParseException
*/
public static Date endDate( Date startDate , int payCycle ) {
SimpleDateFormat dataFormat= new SimpleDateFormat("yyyy-MM-dd");
Calendar cal = Calendar.getInstance();
cal.setTime(startDate);
cal.add(Calendar.MONTH, payCycle) ;
cal.add(Calendar.DATE, -1);
Date time = cal.getTime();
Date theMonthLastDay = getTheMonthLastDay( time ) ;
return theMonthLastDay;
}

/**
* 得到当前月的最后日期
* @throws ParseException
*/
public static Date getTheMonthLastDay( Date date ) {
Calendar cale = null;
cale = Calendar.getInstance();
cale.setTime(date);
cale.add(Calendar.MONTH, 1);
cale.set(Calendar.DAY_OF_MONTH, 0);
return cale.getTime();
}




/**
* 返回 日期 相差月份 忽略天
* @return
*/
public static int intervalMonths( Date startDate, Date endDate ){

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String startStr = simpleDateFormat.format(startDate);
String endStr = simpleDateFormat.format(endDate);

DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
DateTime start = formatter.parseDateTime(startStr);
DateTime end = formatter.parseDateTime(endStr);
int months = Months.monthsBetween(start, end).getMonths();
return months;
}




/**
* 生成合同缴费账单
* @param info
* @param contractStartDate 账期开始日期
* @param endDate 账期结束日期
* @param averagePrice 同总房源的平均单价
* @param payCycle 账期周期
* @return
*/
public ReceiveBillInfo createReceiveBillInfo( ReceiveBillInfo info ,Date contractStartDate, Date endDate , BigDecimal averagePrice,int payCycle ){
ReceiveBillEntryCollection receiveBillEntry = info.getEntrys();
ReceiveBillEntryInfo entryInfo =new ReceiveBillEntryInfo();
entryInfo.setBeginDate(contractStartDate); //起始日期
entryInfo.setEndDate(endDate); //结束日期
Date beforeFifteen = beforeFifteen( contractStartDate);// 招商 应交日期 是起始日期的前15天
entryInfo.setPaymentDate(beforeFifteen);//应交日期
entryInfo.setAmt(averagePrice.multiply(new BigDecimal(30)).multiply(new BigDecimal(payCycle)));// 应收金额=合同总房源的平均单价*30天 (每个整账期认为30天)
receiveBillEntry.add(entryInfo);
info.getEntrys().addCollection(receiveBillEntry);
return info;

}




/**
* 获取当前日期的前15天 ( 招商 应交日期 是起始日期的前15天)
* @throws ParseException
*/
public Date beforeFifteen(Date thisDate) {
//SimpleDateFormat format= new SimpleDateFormat("yyyy-MM-dd");
Calendar cale = null;
// Date thisDate = format.parse("2021-05-30"); //计算循环月
cale = Calendar.getInstance();
cale.setTime(thisDate);
cale.add(Calendar.DAY_OF_MONTH, -15);
return cale.getTime();
//String lastday = format.format(cale.getTime());
}



/**
* 当前日期的前一月日期
* @throws ParseException
*/
public Date beforeMonth( Date thisDate) throws ParseException {
SimpleDateFormat format= new SimpleDateFormat("yyyy-MM-dd");
Calendar cale = Calendar.getInstance();
cale.setTime(thisDate);
cale.add(Calendar.MONTH, -1);
return cale.getTime();
}



/**
* 判断租赁开始日期 是否是月初
*/
public Boolean CheckContractStartDate( Date thisDate ){
SimpleDateFormat format= new SimpleDateFormat("yyyy-MM-dd");
Calendar cale = null;
cale = Calendar.getInstance();
//计算循环月
cale.setTime(thisDate);
// 获取当月第一天和最后一天
String firstday, lastday;
// 获取 月的第一天
cale.add(Calendar.MONTH, 0);
cale.set(Calendar.DAY_OF_MONTH, 1);
firstday = format.format(cale.getTime());
// 获取 月的最后一天
cale = Calendar.getInstance();
cale.setTime(thisDate);
cale.add(Calendar.MONTH, 1);
cale.set(Calendar.DAY_OF_MONTH, 0);
lastday = format.format(cale.getTime());

Date firstDay = null;
try {
firstDay = format.parse(firstday);
} catch (ParseException e) {
e.printStackTrace();
}
if(thisDate.compareTo(firstDay)==0){
return true;
}else{
return false;
}

}





/**
* 判断租赁结束日期 是否是月末
*/
public Boolean CheckContractEndDate( Date thisDate ){
SimpleDateFormat format= new SimpleDateFormat("yyyy-MM-dd");
Calendar cale = null;
cale = Calendar.getInstance();
//计算循环月
cale.setTime(thisDate);
// 获取当月第一天和最后一天
String lastday;


// 获取 月的最后一天
cale = Calendar.getInstance();
cale.setTime(thisDate);
cale.add(Calendar.MONTH, 1);
cale.set(Calendar.DAY_OF_MONTH, 0);
lastday = format.format(cale.getTime());

Date lastDay = null;
try {
lastDay = format.parse(lastday);
} catch (ParseException e) {
e.printStackTrace();
}
if(thisDate.compareTo(lastDay)==0){
return true;
}else{
return false;
}

}




/**
* 计算两个日期 相差月份, 开始日期 比 结束日期大 默认 加一月
*/
public int monthsInterval(Date begin, Date end ){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

String str1 = sdf.format(begin);
String str2 = sdf.format(end);
Calendar bef = Calendar.getInstance();
Calendar aft = Calendar.getInstance();
try {
bef.setTime(sdf.parse(str1));
aft.setTime(sdf.parse(str2));
} catch (ParseException e) {
e.printStackTrace();
}
int surplus = aft.get(Calendar.DATE) - bef.get(Calendar.DATE);
int result = aft.get(Calendar.MONTH) - bef.get(Calendar.MONTH);
int month = (aft.get(Calendar.YEAR) - bef.get(Calendar.YEAR)) * 12;
System.out.println(surplus);
surplus = surplus <= 0 ? 1 : 0;

System.out.println("相差月份:" + (Math.abs(month + result) + surplus));

return (Math.abs(month + result) + surplus);

}





/**
* 根据房源id 计算房源的
*/

public void calculationByRooms (){

DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
DateTime start = formatter.parseDateTime("2017-07-11");
DateTime end = formatter.parseDateTime("2017-11-19");
int months = Months.monthsBetween(start, end).getMonths();
System.out.println(months);


}


















}