今天是值得高兴的一天,什么原因呢。

原来写的一段程序,很糟糕,自己都不愿意看了。今天思考了一上午,推翻原来的思路,按照新的方法重新
构造了一下,两三个小时写完了,很happy.
这是一个计算房租的方法,三个月交一次房租,房租根据园区所在地有增长率,超过了设置的年数,单价就要上涨
原来写的方法用了过多的if else,自己看着也头疼,bug也很多,不足年或不足三个月价格就很难算出来,现在的新方法,
只要有了开始时间和结束时间,房租都会准确的计算出来。

现在的思路是不管房租从何时签,何时结束,不管是否足年, 是否足月。大的方向分两种足月(三个月为一计算单位),不足月。

$start = $arrLeaseAccountData['LEASE_START']; //合同鉴定开始时间
       
        $end   = $arrLeaseAccountData['LEASE_END'];   //合同鉴定结束时间
       
        //租赁合同总共的月数
        $month = round((strtotime($end)-strtotime($start))/30.4/24/3600);
      
        //开始年
        $startYear  = date('Y', strtotime($start));
       
        //开始月份
        $startMonth = date('m', strtotime($start));
       
        //开始天数
        $startDay   = date('d', strtotime($start));
       
        //单价
        $price = $arrLeaseAccountData['RENT_PRICE'];
       
        //补充折扣
        $priceRate = $arrLeaseAccountData['DISCOUNT_RATE']!=''?$arrLeaseAccountData['DISCOUNT_RATE']:0;       
               
        //实际价格
        $nowPrice = $priceRate!==0?round($price * ($priceRate/100), 2):0;
       
        //面积
        $area =  array_sum($arrLeaseAccountData['ROOM_AREA']);
        //递增年       
        $year = $arrLeaseAccountData['RENTAL_GROWTH_YEAR'];
       
        //递增率
        $rate = $arrLeaseAccountData['RENTAL_GROWTH_RATE'];
       
        //补充协议的免租期(天)
        $period = $arrLeaseAccountData['FREE_RATE_PERIOD']!=''?$arrLeaseAccountData['FREE_RATE_PERIOD']:0;
       
        //租赁合同的免租期(天)
        $leasePeriod = $signType==0&&$arrLeaseAccountData['15DAY_FREE_FLG']==1?15:0;
        //租赁保证金的保存
        $leaseAccountModel = new LeaseAccountInfo();
       
        $oneYearDay = round((mktime(0, 0, 0, $startMonth, $startDay, $startYear+1) - mktime(0, 0, 0, $startMonth, $startDay, $startYear))/24/3600/6);
       
        $leaseAccountModel->LEASE_CONTRACT_ID = $arrLeaseAccountData['LEASE_CONTRACT_ID'];
       
        $leaseAccountModel->BUSI_REGIST_ID    = $arrLeaseAccountData['BUSI_REGIST_ID'];  
        $leaseAccountModel->PAY_TYPE = '00';
       
        $CONTRACT_SIGN_DATE = strtotime($arrLeaseAccountData['CONTRACT_SIGN_DATE']);
       
        //保证金付款日期
        $contract_sign_date_day = strrpos($arrLeaseAccountData['LEASE_CONTRACT_NO'], 'XZ')===0?5:3;
       
        $leaseAccountModel->PAY_DATE = date('Ymd', mktime(0, 0, 0, date("m", $CONTRACT_SIGN_DATE), date("d", $CONTRACT_SIGN_DATE)+ $contract_sign_date_day,   date("Y", $CONTRACT_SIGN_DATE)));      
              
        $leaseAccountModel->TOTAL_AMOUNT      = $price * $oneYearDay * $area;
       
        $leaseAccountModel->SUPPLEMENT_TOTAL  = $nowPrice!=0?($nowPrice * $oneYearDay * $area):($price * $oneYearDay * $area);
       
        $leaseAccountModel->save();
               
        for($i=1;$i<=$month+1;$i++){
                
            //每三月计算一次(第一次计算)
            if(($i-1)%12==0){
              
                if($i!=1){ 
                    $model = new LeaseAccountInfo();
               
                    $model->PAY_TYPE = '01';
               
                    $model->LEASE_CONTRACT_ID = $arrLeaseAccountData['LEASE_CONTRACT_ID'];
               
                    $model->BUSI_REGIST_ID    = $arrLeaseAccountData['BUSI_REGIST_ID'];
               
                    $date = new DateTime($thisEnd);
               
                    $date->modify("+1 day");
               
                    $thisStart = $date->format("Ymd");
               
                    $model->RENT_START = $thisStart;
               
                    $date = new DateTime($thisStart);
               
                    $date->modify("-1 month");
               
                    if(strpos($arrLeaseAccountData['LEASE_CONTRACT_NO'], 'XZ')===0){
                       
                       $date->modify('19 day');
                      
                    }else{
                       
                       $date->modify('24 day');
                      
                    }
               
                    $model->PAY_DATE = $date->format('Ymd');
               
                    $date = new DateTime($thisStart);
               
                    $date->modify(($startDay-2)."day");
               
                    $thisEnd = $date->format("Ymd");
                   
                    if($thisEnd>=$end||(date('Y',strtotime($end))==date('Y',strtotime($thisEnd))&&date('m',strtotime($end))==date('m',strtotime($thisEnd)))){
                       
                        $thisEnd = $end;
                    }
                                                    
                    $model->RENT_END = $thisEnd;               
             
                    $dayCount = $this->getCountDate($thisStart, $thisEnd);
               
                    $nowDayCount = $dayCount-$nowPeriod;
               
                    $nowPeriod = $nowDayCount<0?(-$nowDayCount):0;
               
                    $model->RENT_PRICE = $price;
           
                    $model->SUPPLEMENT_RENT = $nowPrice==0?'':$nowPrice;
           
                    //天数
                    $model->LEASE_DAYS = $dayCount>0?$dayCount:0;
               
                    $model->SUPPLEMENT_DAYS = $nowPrice==0?'':($nowDayCount<=0?0:$nowDayCount);
               
                    $model->TOTAL_AMOUNT    = $price * $dayCount * $area;
               
                    $model->SUPPLEMENT_TOTAL = ($nowPrice==0?($price * $dayCount * $area):($nowPrice * $nowDayCount * $area));           
               
                    if ($model->LEASE_DAYS > 0){
                       
                        $model->save();     
                    }
                    if($thisEnd>=$end||(date('Y',strtotime($end))==date('Y',strtotime($thisEnd))&&date('m',strtotime($end))==date('m',strtotime($thisEnd)))){
                         break;
                    } 
                    //租金增长
                   $date = new DateTime($thisEnd);
                  
                   $date->modify('+1 day');
                  
                   $now = $date->format('Ymd');
                  
                   if((intval(($i-1)/12))%$year==0&&($now - $start)>=(10000 * $year)){
                   
                        $z = floor(($now-$start)/(10000 * $year));
                       
                        for($j=0;$j<$z;$j++){
                       
                            //租金单价(元)
                            $price = round($price * (1 + $rate/100), 2);
                       
                            //补充租金单价(元)
                            $nowPrice  = round($nowPrice * (1 + $rate/100), 2);
                           
                        }
                   }   
                }
                   
                $model = new LeaseAccountInfo();
               
                $model->PAY_TYPE = '01';
               
                $model->LEASE_CONTRACT_ID = $arrLeaseAccountData['LEASE_CONTRACT_ID'];
               
                $model->BUSI_REGIST_ID    = $arrLeaseAccountData['BUSI_REGIST_ID'];
               
                if(!isset($thisEnd)){
                   
                    $thisStart = $start;
                   
                }else{
                    $date = new DateTime($thisEnd);
               
                    $date->modify("+1 day");
                   
                    $thisStart = $date->format('Ymd');
                }
               
                $model->RENT_START = $thisStart;
               
                $date = new DateTime(date('Y-m',strtotime($thisStart)));
               
                $date->modify("+3 month");
               
                $date->modify("-1 day");
               
                $thisEnd = $date->format("Ymd");
               
                if($i==1){
                   
                    $payDate = $start;
                   
                }else{
                   
                    $date = new DateTime(date('Y-m',strtotime($thisStart)));
               
                    $date->modify("-1 month");
               
                    if(strpos($arrLeaseAccountData['LEASE_CONTRACT_NO'], 'XZ')===0){
                   
                        $date->modify('19 day');
                  
                    }else{
                   
                        $date->modify('24 day');
                    }
               
                    $payDate = $date->format("Ymd");
                }     
                         
                $model->PAY_DATE = $payDate;
               
                //不足三个月的情况下
                if($thisEnd>=$end){
                    $thisEnd = $end;
                }
                $model->RENT_END = $thisEnd;
               
                $dayCount = $this->getCountDate($thisStart, $thisEnd);
             
                if($i==1){  
                                    
                    $nowDayCount = $dayCount - $period;
                   
                    $dayCount = $dayCount - $leasePeriod;
                   
                } else{
                   
                    $nowDayCount = $dayCount - $nowPeriod;
                }
               
                $nowPeriod = $nowDayCount<0?(-$nowDayCount):0;
               
                $model->RENT_PRICE = $price;
           
                $model->SUPPLEMENT_RENT = $nowPrice==0?'':$nowPrice;
           
                //天数
                $model->LEASE_DAYS = ($dayCount<=0?0:$dayCount);
               
                $model->SUPPLEMENT_DAYS = $nowPrice==0?'':($nowDayCount>0?$nowDayCount:0);
               
                $model->TOTAL_AMOUNT    = $price * $dayCount * $area;
               
                $model->SUPPLEMENT_TOTAL = ($nowPrice==0?($price * $dayCount * $area):($nowPrice * $model->SUPPLEMENT_DAYS * $area));
           
                if ($model->LEASE_DAYS > 0){
               
                    $model->save();     
                }                   
                //不足三个月的情况下
                if($thisEnd>=$end){                   
                   break;
                }
            }elseif(($i-1)%3==0){
               
                $model = new LeaseAccountInfo();
               
                $model->PAY_TYPE = '01';
               
                $model->LEASE_CONTRACT_ID = $arrLeaseAccountData['LEASE_CONTRACT_ID'];
               
                $model->BUSI_REGIST_ID    = $arrLeaseAccountData['BUSI_REGIST_ID'];
               
                $date = new DateTime($thisEnd);
               
                $date->modify("+1 day");
               
                $thisStart = $date->format("Ymd");
               
                $model->RENT_START = $thisStart;
               
                $date = new DateTime($thisStart);
               
                $date->modify("-1 month");
               
                if(strpos($arrLeaseAccountData['LEASE_CONTRACT_NO'], 'XZ')===0){
                   
                   $date->modify('19 day');
                  
                }else{
                   
                   $date->modify('24 day');
                }
               
                $model->PAY_DATE = $date->format('Ymd');
               
                $date = new DateTime($thisStart);
               
                $date->modify("+3 month");
               
                $date->modify("-1 day");
               
                $thisEnd = $date->format("Ymd");
               
                if($thisEnd>=$end){
                    $thisEnd = $end;
                }
               
                $model->RENT_END = $thisEnd;               
             
                $dayCount = $this->getCountDate($thisStart, $thisEnd);
               
                $nowDayCount = $dayCount-$nowPeriod;
               
                $nowPeriod = $nowDayCount<0?(-$nowDayCount):0;
               
                $model->RENT_PRICE = $price;
           
                $model->SUPPLEMENT_RENT = $nowPrice==0?'':$nowPrice;
           
                //天数
                $model->LEASE_DAYS = $dayCount;
               
                $model->SUPPLEMENT_DAYS = $nowPrice==0?'':($nowDayCount<=0?0:$nowDayCount);
               
                $model->TOTAL_AMOUNT    = $price * $dayCount * $area;
               
                $model->SUPPLEMENT_TOTAL = ($nowPrice==0?($price * $dayCount * $area):($nowPrice * $model->SUPPLEMENT_DAYS * $area));           
               
                if ($model->LEASE_DAYS > 0){
                                       
                    $model->save();     
                }  
               
                if($thisEnd>=$end){
                     break;
                }
            }        
        }

 

 

/**

     * 获取两段时间之间的天数
     * Enter description here ...
     * @param date $start
     * @param date $end
     */
    private function getCountDate($thisStart, $thisEnd){
       
        $dayCount = (mktime(0, 0, 0, date('m',strtotime($thisEnd)), date('d',strtotime($thisEnd)), date('Y',strtotime($thisEnd))) - mktime(0, 0, 0, date('m',strtotime($thisStart)), date('d',strtotime($thisStart)), date('Y',strtotime($thisStart))))/24/3600 + 1;
       
        return $dayCount;
    }

 

如果再细细的分析一下,该方法还可以再改进。