//CREATING STYLES
createStyle(name: 'b', fontBold: true)
createStyle(name: 'f10', fontHeight:10)
createStyle(name: 'f11', fontHeight:11)
createStyle(name: 'hl', h_alignment: 'LEFT')
createStyle(name: 'hr', h_alignment: 'RIGHT')
createStyle(name: 'hc', h_alignment: 'CENTER')
createStyle(name: 'vc', v_alignment: 'CENTER')
createStyle(name: 'sp9', h_span: 9)
createStyle(name: 'sp3', h_span: 3)
createStyle(name: 'sp2', h_span: 2)
createStyle(name: 'thin_b', leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN')
createStyle(name: 'medium_b', leftBorder:'MEDIUM', rightBorder:'MEDIUM', topBorder:'MEDIUM', bottomBorder:'MEDIUM')
createStyle(name: 'date', format: 'm/d/yy')
createStyle(name: 'wrap', wrapText: true)
createStyle(name: 'header',fontBold: false,  h_alignment: 'CENTER', v_alignment: 'CENTER', fontHeight:10, leftBorder:'MEDIUM', rightBorder:'MEDIUM', topBorder:'MEDIUM', bottomBorder:'MEDIUM', wrapText: true)

//ADDITIONAL FUNCTIONS
def sum = {BigDecimal... values ->
    BigDecimal result = BigDecimal.ZERO
    values.each {
        if(it != null){
            result = result.add(it)
        }
    }
    return result
}
def multi = {BigDecimal... values ->
    BigDecimal result = BigDecimal.ONE
    values.each {
        if(it == null){
            result == BigDecimal.ZERO
            return
        }
        result = result.multiply(it)
    }
    return result
}

def makeTitle = {
    //TITLE
    rowHeight(30)
    text("Отчет - Акт выполненных работ", 'b|sp9|hl|vc|f11')
    rowHeight(15)
    2.times{nextRow()}
}

def makeMainHeader = {
    text('Доверитель', 'sp3|b|hl|vc|f10')
    nextColumn()
    text(parameters.SUPPLIER_NAME, 'sp3|b|hl|vc|f10|thin_b')

    nextRow()
    text('Код ПП, канал продаж:', 'sp3|b|hl|vc|f10')
    nextColumn()
    text(' ', 'sp2|b|hl|vc|f10|thin_b')
    nextColumn()
    text(' ', 'b|hl|vc|f10|thin_b')

    2.times{nextRow()}
    text('Поверенный:', 'sp3|b|hl|vc|f10')
    nextColumn()
    text(parameters.AGENCY_NAME, 'sp3|b|hl|vc|f10|thin_b')

    nextRow()
    text('№ договора поручения:', 'sp3|b|hl|vc|f10')
    nextColumn()
    text(parameters.SUPPLIER_CONTRACT_NUMBER, 'sp3|b|hl|vc|f10|thin_b')

    nextRow()
    text('дата договора поручения:', 'sp3|b|hl|vc|f10')
    nextColumn()
    date(parameters.SUPPLIER_CONTRACT_ISSUE_DATE, 'sp3|b|hl|vc|f10|thin_b|date')

    nextRow()
    text('Страховой продукт:','sp3|b|hl|vc|f10')
    nextColumn()
    text('НС Авиа', 'sp2|b|hl|vc|f10|thin_b')
    nextColumn()
    text('198', 'b|hl|vc|f10|thin_b')

    nextRow()
    text('№ отчета:', 'sp3|b|hl|vc|f10')
    nextColumn()
    text(' ', 'sp3|b|hl|vc|f10|thin_b')

    2.times{nextRow()}
    text('Отчетный период:', 'sp3|b|hl|vc|f10')
    nextColumn()
    date(parameters['key-report-params'].periodBegin, 'sp2|b|hl|vc|f10|thin_b|date')
    nextColumn()
    date(parameters['key-report-params'].periodEnd, 'b|hl|vc|f10|thin_b|date')

    2.times{nextRow()}
}

def makeTableHeader = { title ->
    text(title, 'b|hl|vc|f10')
    nextRow()
    setStyle('header')
    columnWidth(8)
    text('№ П/П')
    nextColumn()
    columnWidth(8)
    text('Серия')
    nextColumn()
    columnWidth(10)
    text('№  полиса ')
    nextColumn()
    columnWidth(10)
    text('Дата выдачи')
    nextColumn()
    columnWidth(10)
    text('Рейс')
    nextColumn()
    columnWidth(20)
    text('Ф.И.О. Застрахованного')
    nextColumn()
    columnWidth(10)
    text('№ паспорта')
    nextColumn()
    columnWidth(10)
    text('СC, руб.')
    nextColumn()
    columnWidth(10)
    text('СП,руб.')
    nextRow()
    setStyle('normal')
}

def makeSlicesHeader = { title ->
    text(title, 'b|hl|vc|f10')
    nextRow()
    setStyle('header')
    text('CC, руб.')
    nextColumn()
    text('CП, руб.')
    nextColumn()
    text('закл.')
    nextColumn()
    text('CC общ, руб.')
    nextColumn()
    text('CП общ, руб.')
    nextColumn()
    text('расторж.')
    nextColumn()
    text('CC общ, руб.')
    nextColumn()
    text('CП общ, руб.')

    nextRow()
    setStyle('normal')
}

class InsuranceSlice{
    def amount
    def premium

    InsuranceSlice(amount, premium){
        this.amount = amount
        this.premium = premium
    }

    def boolean equals(obj) {
        if (!(obj instanceof InsuranceSlice)) {
           return false
        }
        InsuranceSlice rhs = (InsuranceSlice) obj
        return amount?.compareTo(rhs.amount) == 0 && premium?.compareTo(rhs.premium) == 0
     }

     def int hashCode() {
        def prime = 31;
        def result = 1;
        result = prime * result + amount;
        result = prime * result + premium;
        return result;
     }
}

class InsuranceStats {
    def sellCount
    def voidCount
    def sellAmountTotal
    def sellPremiumTotal
    def voidAmountTotal
    def voidPremiumTotal

    InsuranceStats(){
        sellCount = 0
        voidCount = 0
        sellAmountTotal = 0.0
        sellPremiumTotal = 0.0
        voidAmountTotal = 0.0
        voidPremiumTotal = 0.0
    }
}

def makeSummary = { totalSellCount, totalSellPremiumCell, totalVoidCount, totalVoidPremiumCell ->
    text('Общий итог', 'b|hl|vc|f10')
    nextRow()

    setStyle('text')
    text('1.    Количество заключенных договоров страхования:')
    7.times {nextColumn()}
    number(totalSellCount, 'text')
    nextColumn()
    text('штук')
    nextRow()

    text('2.    Сумма полученной страховой премии:')
    7.times {nextColumn()}
    formula("${totalSellPremiumCell}",'text')
    nextColumn()
    text('рублей')
    nextRow()

    text('3.    Количество аннулированных договоров  страхования:')
    7.times {nextColumn()}
    number(totalVoidCount)
    nextColumn()
    text('штук')
    nextRow()

    text('4.    Сумма страховой премии по аннулированным договорам страхования:')
    7.times {nextColumn()}
    formula("${totalVoidPremiumCell}",'text')
    nextColumn()
    text('рублей')
    nextRow()

    text('5.    Сальдо (полученная премия-аннулированная):')
    7.times {nextColumn()}
    formula("${cellIndex(-3,0)}-${cellIndex(-1,0)}",'text')
    nextColumn()
    text('рублей')
    nextRow()

    text('6.    Комиссионное вознаграждение Поверенного:  ')
    7.times {nextColumn()}
    //number('100')
    // data input manually into the cell
    nextColumn()
    text('%')
    nextRow()

    text('7.    ')
    7.times {nextColumn()}
    formula("${cellIndex(-2,0)}*(${cellIndex(-1,0)}/100)",'text')
    nextColumn()
    text('рублей')
    nextRow()

    text('8.    в том числе НДС  18%:  ')
    7.times {nextColumn()}
    formula("${cellIndex(-1,0)}*0.18",'text')
    nextColumn()
    text('рублей')
    nextRow()

    text('9.   Подлежит перечислению Доверителю: ')
    7.times {nextColumn()}
    formula("${cellIndex(-4,0)}-${cellIndex(-2,0)}",'text')
    nextColumn()
    text('рублей')
    nextRow()

    nextRow()
    setStyle('normal')


}

def makeFooter = {
    text('Доверитель', 'b|h10|hl|vc|hc|sp3')
    setStyle('normal')
    5.times { nextColumn() }
    text('Поверенный', 'b|h10|hl|vc|hc|sp3')
    setStyle('normal')
    2.times{ nextRow() }
    text(parameters.SUPPLIER_NAME, 'b|h10|hc|vc|sp3')
    setStyle('normal')
    5.times { nextColumn() }
    text(parameters.AGENCY_NAME, 'b|h10|hl|vc|hc|sp3')
    setStyle('normal')
    2.times{ nextRow() }

    def accountant = parameters.get('accountant')   // Главный  бухгалтер
    def principal = parameters.get('principal')     // Доверитель
    def attorney = parameters.get('attorney')       // Поверенный

    text('/ ' + (principal ?: '_____________') + ' /', 'sp3|vc|hr')
    setStyle('normal')
    5.times { nextColumn() }
    text('/ ' + (attorney  ?: '_____________') + ' /', 'sp3|vc|hr')
    setStyle('normal')
    nextRow()
    text('\'___\' \'__________\'  2013 г.', 'sp3|vc|hr')
    setStyle('normal')
    5.times { nextColumn() }
    text('\'___\' \'__________\'  2013 г.', 'sp3|vc|hr')
    setStyle('normal')
    nextRow()
    nextRow()

    5.times {nextColumn() }
    text('Главный бухгалтер', 'b|h10|hl|vc|hc|sp3')
    setStyle('normal')
    nextRow()

    5.times { nextColumn() }
    text('/ ' + (accountant  ?: '_____________') + ' /', 'sp3|vc|hr')
    setStyle('normal')
    nextRow()

    5.times { nextColumn() }
    text('\'___\' \'__________\'  2013 г.', 'sp3|vc|hr')
    setStyle('normal')
    nextRow()
}

//REPORT
page{'Worksheet'}{

    makeTitle()
    makeMainHeader()

    def titles = ['SELL':'Заключённые договоры страхования (полисы):', 'VOID':'Аннулированные договоры страхования (полисы):' ]


    //DATA
    def iterNumber = 0
    def slicesMap =[:]
    def totalSellCount = 0
    def totalVoidCount = 0
    def totalSellPremiumCell = null
    def totalVoidPremiumCell = null
    groups{it.status?.toString()}{
        def status = null
        // make these iterations just to determine status
        tickets{
            if (status == null){
                status = it.status?.name()
            }
        }

        makeTableHeader(titles.get(status))
        String amountCell = cellIndex(0,7)
        String premiumCell = cellIndex(0,8)

        def num = 1
        tickets{
            number(num,'text')
            num++
            nextColumn()
            text("АЛЬФ", 'text')
            nextColumn()
            text(it.systemNumber,'text')
            nextColumn()
            date(it.issueDate,'date')
            setStyle('normal')
            nextColumn()
            nextColumn()
            text(it.traveler,'text')
            nextColumn()
            text(it.passportNumber,'text')
            nextColumn()
            number(it.amount,'text')
            nextColumn()
            number(it.premium,'text')
            nextRow()

            InsuranceSlice slice = new InsuranceSlice(it.amount, it.premium)
            if (!slicesMap.containsKey(slice)){
                slicesMap.put(slice, new InsuranceStats())
            }
            InsuranceStats stats = slicesMap.get(slice)
            if ('SELL'.equals(it.status?.name())){
                stats.sellCount++
                stats.sellAmountTotal += it.amount
                stats.sellPremiumTotal += it.premium
                totalSellCount++
                //totalSellPremium += it.premium
            } else if ('VOID'.equals(it.status?.name())){
                stats.voidCount++
                stats.voidAmountTotal += it.amount
                stats.voidPremiumTotal += it.premium
                totalVoidCount++
                //totalVoidPremium += it.premium
            }
        }
        //SUBTOTAL
        text('Всего','subtotalTitle')
        7.times{nextColumn()}
        formula("SUM(${amountCell}:${cellIndex(-1,0)})",'text')
        nextColumn()
        formula("SUM(${premiumCell}:${cellIndex(-1,0)})",'text')

    if ('SELL'.equals(status)){
                totalSellPremiumCell = cellIndex(0,0)
        } else if ('VOID'.equals(status)){
        totalVoidPremiumCell = cellIndex(0,0)
    }
        2.times{nextRow()}
        iterNumber++
    }

    makeSlicesHeader('В разрезе комбинаций СС и СП')

    slicesMap.each {key, value ->
        number(key.amount,'text')
        nextColumn()
        number(key.premium,'text')
        nextColumn()
        number(value.sellCount,'text')
        nextColumn()
        number(value.sellAmountTotal,'text')
        nextColumn()
        number(value.sellPremiumTotal,'text')
        nextColumn()
        number(value.voidCount,'text')
        nextColumn()
        number(value.voidAmountTotal,'text')
        nextColumn()
        number(value.voidPremiumTotal,'text')
        nextRow()
    }

    makeSummary(totalSellCount, totalSellPremiumCell, totalVoidCount, totalVoidPremiumCell)

    makeFooter()
}