java110 лет назад: 6
Родитель
Сommit
5ac834ecdf

+ 547 - 0
service-job/src/main/java/com/java110/job/task/fee/GenerateBillProTemplate.java

@@ -0,0 +1,547 @@
+package com.java110.job.task.fee;
+
+import com.java110.core.factory.GenerateCodeFactory;
+import com.java110.dto.RoomDto;
+import com.java110.dto.community.CommunityDto;
+import com.java110.dto.fee.*;
+import com.java110.dto.owner.OwnerCarDto;
+import com.java110.dto.owner.OwnerRoomRelDto;
+import com.java110.dto.parking.ParkingSpaceDto;
+import com.java110.dto.task.TaskDto;
+import com.java110.intf.community.IParkingSpaceInnerServiceSMO;
+import com.java110.intf.community.IRoomInnerServiceSMO;
+import com.java110.intf.fee.IFeeConfigInnerServiceSMO;
+import com.java110.intf.fee.IFeeDetailInnerServiceSMO;
+import com.java110.intf.fee.IFeeInnerServiceSMO;
+import com.java110.intf.user.IOwnerCarInnerServiceSMO;
+import com.java110.intf.user.IOwnerRoomRelInnerServiceSMO;
+import com.java110.job.quartz.TaskSystemQuartz;
+import com.java110.utils.constant.ResponseConstant;
+import com.java110.utils.exception.TaskTemplateException;
+import com.java110.utils.util.DateUtil;
+import com.java110.utils.util.StringUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @ClassName GenerateOwnerBillTemplate
+ * @Description TODO  房屋费用账单生成
+ * @Author wuxw
+ * @Date 2020/6/4 8:33
+ * @Version 1.0
+ * add by wuxw 2020/6/4
+ **/
+@Component
+public class GenerateBillProTemplate extends TaskSystemQuartz {
+    private static final String TASK_ATTR_BILL_TYPE = "10002"; // 出账类型
+
+    private static final String TASK_ATTR_VALUE_MONTH = "002"; //按月出账
+
+    private static final String TASK_ATTR_VALUE_DAY = "003"; //按日出账
+
+    private static final String TASK_ATTR_VALUE_YEAR = "001"; //按年出账
+
+    private static final String TASK_ATTR_VALUE_ONCE_MONTH = "005"; //一次性按月出账
+
+    @Autowired
+    private IFeeConfigInnerServiceSMO feeConfigInnerServiceSMOImpl;
+
+    @Autowired
+    private IFeeInnerServiceSMO feeInnerServiceSMOImpl;
+
+    @Autowired
+    private IFeeDetailInnerServiceSMO feeDetailInnerServiceSMOImpl;
+
+    @Autowired
+    private IRoomInnerServiceSMO roomInnerServiceSMOImpl;
+
+    @Autowired
+    private IOwnerRoomRelInnerServiceSMO ownerRoomRelInnerServiceSMOImpl;
+
+    @Autowired
+    private IParkingSpaceInnerServiceSMO parkingSpaceInnerServiceSMOImpl;
+
+    @Autowired
+    private IOwnerCarInnerServiceSMO ownerCarInnerServiceSMOImpl;
+
+
+    @Override
+    protected void process(TaskDto taskDto) throws Exception {
+
+        // 获取小区
+        List<CommunityDto> communityDtos = getAllCommunity();
+
+        for (CommunityDto communityDto : communityDtos) {
+            GenerateBill(taskDto, communityDto);
+        }
+
+    }
+
+    /**
+     * 根据小区生成账单
+     *
+     * @param communityDto
+     */
+    private void GenerateBill(TaskDto taskDto, CommunityDto communityDto) {
+
+        //查询费用项
+        FeeConfigDto feeConfigDto = new FeeConfigDto();
+        feeConfigDto.setCommunityId(communityDto.getCommunityId());
+        feeConfigDto.setBillType(getCurTaskAttr(taskDto, TASK_ATTR_BILL_TYPE).getValue());
+
+        if (StringUtil.isEmpty(feeConfigDto.getBillType())) {
+            throw new IllegalArgumentException("配置错误 未拿到属性值");
+        }
+        List<FeeConfigDto> feeConfigDtos = feeConfigInnerServiceSMOImpl.queryFeeConfigs(feeConfigDto);
+
+        for (FeeConfigDto tmpFeeConfigDto : feeConfigDtos) {
+            try {
+                GenerateBillByFeeConfig(taskDto, tmpFeeConfigDto);
+            } catch (Exception e) {
+                logger.error("费用出账失败" + tmpFeeConfigDto.getConfigId(), e);
+            }
+        }
+
+
+    }
+
+    /**
+     * 按费用项来出账
+     *
+     * @param taskDto
+     * @param feeConfigDto
+     */
+    private void GenerateBillByFeeConfig(TaskDto taskDto, FeeConfigDto feeConfigDto) throws Exception {
+
+        //当前费用项是否
+        BillDto tmpBillDto = new BillDto();
+        tmpBillDto.setCurBill("T");
+        tmpBillDto.setConfigId(feeConfigDto.getConfigId());
+        tmpBillDto.setCommunityId(feeConfigDto.getCommunityId());
+        Date startTime = getDefaultStartTime(feeConfigDto.getBillType());
+        tmpBillDto.setCurBillTime(DateUtil.getFormatTimeString(startTime, DateUtil.DATE_FORMATE_STRING_A));
+        List<BillDto> billDtos = feeInnerServiceSMOImpl.queryBills(tmpBillDto);
+
+        //Assert.listOnlyOne(billDtos, "当前存在多个有效账单" + feeConfigDto.getConfigId());
+        if (billDtos != null && billDtos.size() > 0) {
+            throw new TaskTemplateException(ResponseConstant.RESULT_CODE_ERROR, "已经出过账了");
+        }
+
+        String billId = GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_billId);
+        BillDto billDto = new BillDto();
+        billDto.setBillId(billId);
+        billDto.setBillName(feeConfigDto.getFeeName() + "-" + DateUtil.getFormatTimeString(new Date(), DateUtil.DATE_FORMATE_STRING_H));
+        billDto.setBillTime(DateUtil.getFormatTimeString(new Date(), DateUtil.DATE_FORMATE_STRING_A));
+        billDto.setCommunityId(feeConfigDto.getCommunityId());
+        billDto.setConfigId(feeConfigDto.getConfigId());
+        billDto.setCurBill("T");
+        //查询历史有效账单
+        tmpBillDto = new BillDto();
+        tmpBillDto.setCurBill("T");
+        tmpBillDto.setConfigId(feeConfigDto.getConfigId());
+        tmpBillDto.setCommunityId(feeConfigDto.getCommunityId());
+        billDtos = feeInnerServiceSMOImpl.queryBills(tmpBillDto);
+
+        startTime = (billDtos == null || billDtos.size() < 1) ? getDefaultStartTime(feeConfigDto.getBillType())
+                : DateUtil.getDateFromString(billDtos.get(0).getBillTime(), DateUtil.DATE_FORMATE_STRING_A);
+
+        FeeDto feeDto = new FeeDto();
+        feeDto.setConfigId(feeConfigDto.getConfigId());
+        feeDto.setCommunityId(feeConfigDto.getCommunityId());
+        List<FeeDto> feeDtos = feeInnerServiceSMOImpl.queryFees(feeDto);
+
+        //没有关联费用不做出账
+        if (feeDto == null || feeDtos.size() < 1) {
+            return;
+        }
+        billDto.setReceivable("0");
+        billDto.setReceipts("0");
+        billDto.setCurReceivable("0");
+        for (FeeDto tmpFeeDto : feeDtos) {
+            try {
+                generateFee(startTime, tmpFeeDto, billDto, feeConfigDto);
+            } catch (Exception e) {
+                logger.error("生成费用失败", e);
+            }
+        }
+
+
+        //生成本次账单
+        Date billEndTime = DateUtil.getCurrentDate();
+        billDto.setRemark(DateUtil.getFormatTimeString(startTime, DateUtil.DATE_FORMATE_STRING_A) +
+                "-" + DateUtil.getFormatTimeString(billEndTime, DateUtil.DATE_FORMATE_STRING_A) + "账单数据");
+        feeInnerServiceSMOImpl.insertBill(billDto);
+
+    }
+
+    /**
+     * 生成 费用
+     *
+     * @param feeDto
+     */
+    private void generateFee(Date startTime, FeeDto feeDto, BillDto billDto, FeeConfigDto feeConfigDto) {
+
+        if ("2009001".equals(feeDto.getState())) { //判断是否缴费结束
+            return;
+        }
+
+        // 当前时间 - 开始时间  = 月份
+        // 月份/ 周期 = 轮数(向上取整)
+        // 轮数 * 周期 * 30 + 开始时间 = 目标 到期时间
+        // 到期时间 >= 目标到期时间===>结束
+        // 目标到期时间 - 到期时间 = 欠费月份
+        // 月份 * 每月单价 = 欠费金额
+
+        //当前时间
+        Date billEndTime = DateUtil.getCurrentDate();
+        //开始时间
+        Date startDate = feeDto.getStartTime();
+        //到期时间
+        Date endDate = feeDto.getEndTime();
+        //缴费周期
+        long paymentCycle = Long.parseLong(feeConfigDto.getPaymentCycle());
+        // 当前时间 - 开始时间  = 月份
+        double mulMonth = dayCompare(startDate, billEndTime);
+        // 月份/ 周期 = 轮数(向上取整)
+        double round = 0.0;
+        if ("1200".equals(feeConfigDto.getPaymentCd())) { // 预付费
+            round = Math.floor(mulMonth / paymentCycle) + 1;
+        } else { //后付费
+            round = Math.floor(mulMonth / paymentCycle);
+        }
+        // 轮数 * 周期 * 30 + 开始时间 = 目标 到期时间
+        Date targetEndDate = getTargetEndTime(round * paymentCycle * 30, startDate);
+
+        //说明没有欠费
+        if (endDate.getTime() > targetEndDate.getTime()) {
+            return;
+        }
+
+        // 目标到期时间 - 到期时间 = 欠费月份
+        double oweMonth = dayCompare(endDate, targetEndDate);
+
+
+        if (FeeDto.PAYER_OBJ_TYPE_ROOM.equals(feeDto.getPayerObjType())) {
+            computeFeePriceByRoom(feeDto);
+        } else if (FeeDto.PAYER_OBJ_TYPE_PARKING_SPACE.equals(feeDto.getPayerObjType())) {
+            computeFeePriceByParkingSpace(feeDto);
+        } else {
+            return;//这个没有欠费可算
+            //throw new IllegalArgumentException("暂不支持该类型出账" + feeDto.getFeeId());
+        }
+
+        if (feeDto.getFeePrice() <= 0) {
+            return;//这个没有欠费可算
+        }
+
+        BillOweFeeDto billOweFeeDto = new BillOweFeeDto();
+        billOweFeeDto.setOweId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_oweId));
+        billOweFeeDto.setFeeId(feeDto.getFeeId());
+        billOweFeeDto.setBillId(billDto.getBillId());
+        BigDecimal curFeePrice = new BigDecimal(feeDto.getFeePrice());
+        curFeePrice = curFeePrice.multiply(new BigDecimal(paymentCycle));
+        billOweFeeDto.setAmountOwed(curFeePrice.doubleValue() + "");
+        BigDecimal feePrice = new BigDecimal(feeDto.getFeePrice());
+        feePrice = feePrice.multiply(new BigDecimal(oweMonth));
+
+        billOweFeeDto.setBillAmountOwed(feePrice.doubleValue() + "");
+        billOweFeeDto.setFeeEndTime(DateUtil.getFormatTimeString(feeDto.getEndTime(), DateUtil.DATE_FORMATE_STRING_A));
+        billOweFeeDto.setCommunityId(feeDto.getCommunityId());
+        billOweFeeDto.setPayerObjType(feeDto.getPayerObjType());
+        billOweFeeDto.setState("1000");
+
+        if ("3333".equals(feeDto.getPayerObjType())) {
+            getRoomInfo(billOweFeeDto, feeDto);
+        } else {
+            getParkingSpaceInfo(billOweFeeDto, feeDto);
+        }
+
+        feeInnerServiceSMOImpl.insertBillOweFees(billOweFeeDto);
+
+        double recFee = StringUtil.isEmpty(billDto.getReceivable()) ? 0.0 : Double.parseDouble(billDto.getReceivable());
+
+        BigDecimal recFeeBig = new BigDecimal(recFee);
+        BigDecimal newRecFee = recFeeBig.add(feePrice);
+
+        //应收
+        billDto.setReceivable(newRecFee.doubleValue() + "");
+
+        //当期应收
+        double curRecFee = StringUtil.isEmpty(billDto.getCurReceivable()) ? 0.0 : Double.parseDouble(billDto.getCurReceivable());
+        BigDecimal curRecFeeBig = new BigDecimal(curRecFee);
+        BigDecimal curNewRecFee = curRecFeeBig.add(curFeePrice);
+        billDto.setCurReceivable(curNewRecFee.doubleValue() + "");
+
+        FeeDetailDto feeDetailDto = new FeeDetailDto();
+        feeDetailDto.setFeeId(feeDto.getFeeId());
+        feeDetailDto.setCommunityId(feeDto.getCommunityId());
+        feeDetailDto.setStartTime(startTime);
+        feeDetailDto.setEndTime(billEndTime);
+        List<FeeDetailDto> feeDetailDtos = feeDetailInnerServiceSMOImpl.queryFeeDetails(feeDetailDto);
+
+        double curReceiptFee = StringUtil.isEmpty(billDto.getReceipts()) ? 0.0 : Double.parseDouble(billDto.getReceipts());
+        BigDecimal curReceipts = new BigDecimal(curReceiptFee);
+        if (feeDetailDtos != null && feeDetailDtos.size() > 0) {
+            for (FeeDetailDto tmpFeeDetailDto : feeDetailDtos) {
+                BigDecimal recAmount = new BigDecimal(Double.parseDouble(tmpFeeDetailDto.getReceivedAmount()));
+                curReceipts = recAmount.add(curReceipts);
+            }
+        }
+
+        billDto.setReceipts(curReceipts.doubleValue() + "");
+
+
+    }
+
+    private Date getTargetEndTime(double v, Date startDate) {
+        Calendar endDate = Calendar.getInstance();
+        endDate.setTime(startDate);
+        endDate.add(Calendar.DATE, (int) v);
+        return endDate.getTime();
+    }
+
+
+    /**
+     * 查询车位信息
+     *
+     * @param billOweFeeDto
+     * @param feeDto
+     */
+    private void getParkingSpaceInfo(BillOweFeeDto billOweFeeDto, FeeDto feeDto) {
+
+        ParkingSpaceDto parkingSpaceDto = new ParkingSpaceDto();
+        parkingSpaceDto.setPsId(feeDto.getPayerObjId());
+        parkingSpaceDto.setCommunityId(feeDto.getCommunityId());
+        List<ParkingSpaceDto> parkingSpaceDtos = parkingSpaceInnerServiceSMOImpl.queryParkingSpaces(parkingSpaceDto);
+        if (parkingSpaceDtos == null || parkingSpaceDtos.size() < 1) {
+            //车位可能被删除了
+            billOweFeeDto.setOwnerId("1");
+            billOweFeeDto.setOwnerName("未知");
+            billOweFeeDto.setOwnerTel("19999999999");
+            billOweFeeDto.setPayerObjName("未知");
+            return;
+        }
+
+        billOweFeeDto.setPayerObjName(parkingSpaceDtos.get(0).getAreaNum() + "停车场" + parkingSpaceDtos.get(0).getNum() + "车位");
+
+
+        OwnerCarDto ownerCarDto = new OwnerCarDto();
+        ownerCarDto.setWithOwner(true);
+        ownerCarDto.setPsId(parkingSpaceDtos.get(0).getPsId());
+        ownerCarDto.setCommunityId(feeDto.getCommunityId());
+
+        List<OwnerCarDto> ownerCarDtos = ownerCarInnerServiceSMOImpl.queryOwnerCars(ownerCarDto);
+
+
+        if (ownerCarDtos == null || ownerCarDtos.size() < 1) {
+            //房屋可能被删除了
+            billOweFeeDto.setOwnerId("1");
+            billOweFeeDto.setOwnerName("未知");
+            billOweFeeDto.setOwnerTel("19999999999");
+            return;
+        }
+
+        billOweFeeDto.setOwnerId(ownerCarDtos.get(0).getOwnerId());
+        billOweFeeDto.setOwnerName(ownerCarDtos.get(0).getOwnerName());
+        billOweFeeDto.setOwnerTel(ownerCarDtos.get(0).getLink());
+    }
+
+    /**
+     * 查询房屋信息
+     *
+     * @param billOweFeeDto
+     * @param feeDto
+     */
+    private void getRoomInfo(BillOweFeeDto billOweFeeDto, FeeDto feeDto) {
+        RoomDto roomDto = new RoomDto();
+        roomDto.setRoomId(feeDto.getPayerObjId());
+        roomDto.setCommunityId(feeDto.getCommunityId());
+        List<RoomDto> roomDtos = roomInnerServiceSMOImpl.queryRooms(roomDto);
+
+        if (roomDtos == null || roomDtos.size() < 1) {
+            //房屋可能被删除了
+            billOweFeeDto.setOweId("1");
+            billOweFeeDto.setOwnerName("未知");
+            billOweFeeDto.setOwnerTel("19999999999");
+            billOweFeeDto.setPayerObjName("未知");
+            return;
+        }
+
+        RoomDto tmpRoomDto = roomDtos.get(0);
+
+        billOweFeeDto.setPayerObjName(tmpRoomDto.getFloorNum() + "栋" + tmpRoomDto.getUnitNum() + "单元" + tmpRoomDto.getRoomNum() + "室");
+
+        OwnerRoomRelDto ownerRoomRelDto = new OwnerRoomRelDto();
+        ownerRoomRelDto.setByOwnerInfo(true);
+        ownerRoomRelDto.setRoomId(tmpRoomDto.getRoomId());
+        List<OwnerRoomRelDto> ownerRoomRelDtos = ownerRoomRelInnerServiceSMOImpl.queryOwnerRoomRels(ownerRoomRelDto);
+
+        if (ownerRoomRelDtos == null || ownerRoomRelDtos.size() < 1) {
+            //房屋可能被删除了
+            billOweFeeDto.setOweId("1");
+            billOweFeeDto.setOwnerName("未知");
+            billOweFeeDto.setOwnerTel("19999999999");
+            return;
+        }
+
+        billOweFeeDto.setOwnerId(ownerRoomRelDtos.get(0).getOwnerId());
+        billOweFeeDto.setOwnerName(ownerRoomRelDtos.get(0).getOwnerName());
+        billOweFeeDto.setOwnerTel(ownerRoomRelDtos.get(0).getLink());
+
+    }
+
+    private Date getDefaultStartTime(String billType) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(new Date());
+        if (billType.equals(TASK_ATTR_VALUE_MONTH)) {
+            calendar.add(Calendar.MONTH, -1);
+            return calendar.getTime();
+        }
+
+        if (billType.equals(TASK_ATTR_VALUE_DAY)) {
+            calendar.add(Calendar.DATE, -1);
+            return calendar.getTime();
+        }
+
+        if (billType.equals(TASK_ATTR_VALUE_DAY)) {
+            calendar.add(Calendar.DATE, -1);
+            return calendar.getTime();
+        }
+
+        if (billType.equals(TASK_ATTR_VALUE_YEAR)) {
+            calendar.add(Calendar.YEAR, -1);
+            return calendar.getTime();
+        }
+
+        return calendar.getTime();
+
+    }
+
+    /**
+     * 根据房屋来算单价
+     *
+     * @param feeDto
+     */
+    private void computeFeePriceByRoom(FeeDto feeDto) {
+        RoomDto roomDto = new RoomDto();
+        roomDto.setCommunityId(feeDto.getCommunityId());
+        roomDto.setRoomId(feeDto.getPayerObjId());
+        List<RoomDto> roomDtos = roomInnerServiceSMOImpl.queryRooms(roomDto);
+
+        if (roomDtos == null || roomDtos.size() < 1) { //数据有问题
+            return;
+        }
+
+        String computingFormula = feeDto.getComputingFormula();
+        double feePrice = 0.00;
+        if ("1001".equals(computingFormula)) { //面积*单价+附加费
+            BigDecimal squarePrice = new BigDecimal(Double.parseDouble(feeDto.getSquarePrice()));
+            BigDecimal builtUpArea = new BigDecimal(Double.parseDouble(roomDtos.get(0).getBuiltUpArea()));
+            BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(feeDto.getAdditionalAmount()));
+            feePrice = squarePrice.multiply(builtUpArea).add(additionalAmount).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue();
+        } else if ("2002".equals(computingFormula)) { // 固定费用
+            BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(feeDto.getAdditionalAmount()));
+            feePrice = additionalAmount.setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue();
+        } else {
+            feePrice = -1.00;
+        }
+
+        feeDto.setFeePrice(feePrice);
+
+        //查询业主信息
+
+
+    }
+
+    /**
+     * 根据车位来算单价
+     *
+     * @param feeDto
+     */
+    private void computeFeePriceByParkingSpace(FeeDto feeDto) {
+        ParkingSpaceDto parkingSpaceDto = new ParkingSpaceDto();
+        parkingSpaceDto.setCommunityId(feeDto.getCommunityId());
+        parkingSpaceDto.setPsId(feeDto.getPayerObjId());
+        List<ParkingSpaceDto> parkingSpaceDtos = parkingSpaceInnerServiceSMOImpl.queryParkingSpaces(parkingSpaceDto);
+
+        if (parkingSpaceDtos == null || parkingSpaceDtos.size() < 1) { //数据有问题
+            return;
+        }
+
+        String computingFormula = feeDto.getComputingFormula();
+        double feePrice = 0.00;
+        if ("1001".equals(computingFormula)) { //面积*单价+附加费
+            BigDecimal squarePrice = new BigDecimal(Double.parseDouble(feeDto.getSquarePrice()));
+            BigDecimal builtUpArea = new BigDecimal(Double.parseDouble(parkingSpaceDtos.get(0).getArea()));
+            BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(feeDto.getAdditionalAmount()));
+            feePrice = squarePrice.multiply(builtUpArea).add(additionalAmount).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue();
+        } else if ("2002".equals(computingFormula)) { // 固定费用
+            BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(feeDto.getAdditionalAmount()));
+            feePrice = additionalAmount.setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue();
+        } else {
+            feePrice = -1.00;
+        }
+
+        feeDto.setFeePrice(feePrice);
+    }
+
+    /**
+     * 计算2个日期之间相差的  以年、月、日为单位,各自计算结果是多少
+     * 比如:2011-02-02 到  2017-03-02
+     * 以年为单位相差为:6年
+     * 以月为单位相差为:73个月
+     * 以日为单位相差为:2220天
+     *
+     * @param fromDate
+     * @param toDate
+     * @return
+     */
+    public static int monthCompare(Date fromDate, Date toDate) {
+        Calendar from = Calendar.getInstance();
+        from.setTime(fromDate);
+        Calendar to = Calendar.getInstance();
+        to.setTime(toDate);
+        //只要年月
+        int fromYear = from.get(Calendar.YEAR);
+        int fromMonth = from.get(Calendar.MONTH);
+        int toYear = to.get(Calendar.YEAR);
+        int toMonth = to.get(Calendar.MONTH);
+        int month = toYear * 12 + toMonth - (fromYear * 12 + fromMonth);
+        return month;
+    }
+
+    /**
+     * 计算2个日期之间相差的  以年、月、日为单位,各自计算结果是多少
+     * 比如:2011-02-02 到  2017-03-02
+     * 以年为单位相差为:6年
+     * 以月为单位相差为:73个月
+     * 以日为单位相差为:2220天
+     *
+     * @param fromDate
+     * @param toDate
+     * @return
+     */
+    public static double dayCompare(Date fromDate, Date toDate) {
+        Calendar from = Calendar.getInstance();
+        from.setTime(fromDate);
+        Calendar to = Calendar.getInstance();
+        to.setTime(toDate);
+
+        long t1 = from.getTimeInMillis();
+        long t2 = to.getTimeInMillis();
+        long days = (t2 - t1) / (24 * 60 * 60 * 1000);
+
+        BigDecimal tmpDays = new BigDecimal(days);
+        BigDecimal monthDay = new BigDecimal(30);
+
+        return tmpDays.divide(monthDay, 2, RoundingMode.HALF_UP).doubleValue();
+    }
+
+
+}