/*
 *
 *  Copyright 2012-2013 Eurocommercial Properties NV
 *
 *
 *  Licensed under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */
package org.estatio.fixturescripts;

import java.util.concurrent.Callable;

import org.apache.commons.lang3.ObjectUtils;
import org.joda.time.LocalDate;

import org.apache.isis.core.commons.exceptions.IsisApplicationException;

import org.estatio.dom.lease.LeaseTerm;
import org.estatio.dom.lease.LeaseTermForIndexableRent;
import org.estatio.dom.lease.LeaseTerms;

public class FixLeaseTerms implements Callable<Object> {

    @Override
    public Object call() throws Exception {
        int countEffectiveDate = 0;
        int countBaseStartDate = 0;
        for (LeaseTerm term : leaseTerms.allLeaseTerms()) {
            if (term instanceof LeaseTermForIndexableRent) {
                if (fixEffectiveDate((LeaseTermForIndexableRent) term)) {
                    countEffectiveDate++;
                }
                if (fixBaseIndexStartDate((LeaseTermForIndexableRent) term)) {
                    countBaseStartDate++;
                }
            }
        }
        return String.format("%d effective dates fixed, %d base index dates fixed", countEffectiveDate, countBaseStartDate);
    }

    private boolean fixBaseIndexStartDate(LeaseTermForIndexableRent term) {
        try {
            if (term.getNext() == null) {
                LeaseTermForIndexableRent previous = (LeaseTermForIndexableRent) term.getPrevious();
                if (previous != null) {
                    LocalDate nextIndexStartDate = previous.getNextIndexStartDate();
                    if (nextIndexStartDate != null && (term.getBaseIndexStartDate() == null || term.getBaseIndexStartDate().compareTo(nextIndexStartDate) != 0)) {
                        term.setBaseIndexStartDate(nextIndexStartDate);
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            throw new IsisApplicationException();
        }
        return false;
    }

    private boolean fixEffectiveDate(LeaseTermForIndexableRent term) {
        LocalDate indexAvailableDate = term.getNextIndexStartDate() == null ? null : term.getNextIndexStartDate().plusMonths(2).plusDays(16);
        LocalDate effectiveDate = null;
        if (indexAvailableDate != null 
                && indexAvailableDate.compareTo(term.getStartDate()) > 0 
                && term.getSettledValue() == null) {
            effectiveDate = term.getLeaseItem().getInvoicingFrequency().intervalContaining(indexAvailableDate).endDateExcluding();
        }
        if (!ObjectUtils.equals(effectiveDate, term.getEffectiveDate())){
            term.setEffectiveDate(effectiveDate);
            return true;
        }
        return false;
    }

    private LeaseTerms leaseTerms;

    public void injectLeaseTerms(LeaseTerms leaseTerms) {
        this.leaseTerms = leaseTerms;
    }

}

@@ -671,16 +671,45 @@
 ripts;%0A%0A
+import java.math.BigDecimal;%0A
 import j
@@ -738,16 +738,16 @@
 llable;%0A
-
 %0Aimport 
@@ -1209,32 +1209,64 @@
 eStartDate = 0;%0A
+        int countLevelling = 0;%0A
         for (Lea
@@ -1496,32 +1496,168 @@
               %7D%0A
+                if (fixLevellingPercentage((LeaseTermForIndexableRent) term)) %7B%0A                    countLevelling++;%0A                %7D%0A
                 
@@ -1875,24 +1875,56 @@
 index dates 
+fixed, %25d levelling percentages 
 fixed%22, coun
@@ -1953,24 +1953,40 @@
 aseStartDate
+, countLevelling
 );%0A    %7D%0A%0A  
@@ -2780,32 +2780,908 @@
 n false;%0A    %7D%0A%0A
+    private boolean fixLevellingPercentage(LeaseTermForIndexableRent term) %7B%0A        try %7B%0A            if (term.getNext() == null) %7B%0A                // last term%0A                LeaseTermForIndexableRent previous = (LeaseTermForIndexableRent) term.getPrevious();%0A                if (previous != null) %7B%0A                    final BigDecimal levellingPercentage = previous.getLevellingPercentage();%0A                    if (levellingPercentage != null) %7B%0A                        if (ObjectUtils.notEqual(levellingPercentage, term.getLevellingPercentage())) %7B%0A                            term.setLevellingPercentage(levellingPercentage);%0A                            return true;%0A                        %7D%0A                    %7D%0A                %7D%0A            %7D%0A        %7D catch (Exception e) %7B%0A            throw new IsisApplicationException();%0A        %7D%0A        return false;%0A    %7D%0A%0A
     private bool
@@ -3955,17 +3955,16 @@
  != null
- 
 %0A       
@@ -4028,17 +4028,16 @@
 e()) %3E 0
- 
 %0A       
@@ -4215,32 +4215,32 @@
 ng();%0A        %7D%0A
-
         if (!Obj
@@ -4295,16 +4295,17 @@
 Date()))
+ 
 %7B%0A      

add fix for levelling percentage to lease term script