import com.gridnine.xtrip.common.l10n.model.LocaleHelper
import com.gridnine.xtrip.common.l10n.model.LocaleManager
import com.gridnine.xtrip.common.l10n.model.PersonalLocalizableNameUtil
import com.gridnine.xtrip.common.model.EntityContainer
import com.gridnine.xtrip.common.model.EntityReference
import com.gridnine.xtrip.common.model.booking.OperationBatch
import com.gridnine.xtrip.common.model.booking.ProductStatus
import com.gridnine.xtrip.common.model.booking.TransportationType
import com.gridnine.xtrip.common.model.booking.air.Tax
import com.gridnine.xtrip.common.model.dict.MCOCategory
import com.gridnine.xtrip.common.model.entity.EntityStorage
import com.gridnine.xtrip.common.model.profile.Person
import com.gridnine.xtrip.common.model.system.PaymentType
import com.gridnine.xtrip.common.reports.model.AirTicketsTemplateReportTicket
import com.gridnine.xtrip.common.util.MiscUtil
import com.gridnine.xtrip.common.util.TextUtil

import java.text.DateFormatSymbols
import java.text.SimpleDateFormat

//CREATING STYLES
createStyle(name: "left", h_alignment: "LEFT")
createStyle(name: "right", h_alignment: "RIGHT")
createStyle(name: "center", h_alignment: "CENTER")
createStyle(name: "left-bold", h_alignment: "LEFT", fontBold : true)
createStyle(name: "right-bold", h_alignment: "RIGHT", fontBold : true)
createStyle(name: "center-bold", h_alignment: "CENTER", fontBold : true)
createStyle(name: "center-center-bold", h_alignment: "CENTER", v_alignment: "CENTER", fontBold : true)
createStyle(name: "left-bold-border", h_alignment: "LEFT", fontBold : true, leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "left-center-bold-border", h_alignment: "LEFT", v_alignment: "CENTER", fontBold : true, leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "right-bold-border", h_alignment: "RIGHT", fontBold : true, leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "right-bold-border-number", format: '#,##0.00', h_alignment: "RIGHT", fontBold : true, leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "center-bold-border", h_alignment: "CENTER", fontBold : true, leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "left-border", h_alignment: "LEFT", leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "right-border", h_alignment: "RIGHT", leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "right-border-number", format: '#,##0.00', h_alignment: "RIGHT", leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "center-border", h_alignment: "CENTER", leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "center-center-border", h_alignment: "CENTER", v_alignment: "CENTER", leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "center-border-number", h_alignment: "CENTER", leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)
createStyle(name: "center-center-border-number", h_alignment: "CENTER", v_alignment: "CENTER", leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', wrapText: true)

//ADDITIONAL FUNCTIONS
class Formula {
    String formula

    Formula (String formula) {
        this.formula = formula
    }
}

Formula sumRow() {
    return new Formula(createSumFormula(0, 1, 0, 3))
}

Formula columnRow(int rowShiftStart, int rowShiftEnd) {
    return new Formula(createSumFormula(rowShiftStart, 0, rowShiftEnd,0))
}

String createSumFormula(int rowShiftStart, int columnShiftStart, int rowShiftEnd, int columnShiftEnd) {
    return "SUM(${cellIndex(rowShiftStart, columnShiftStart)}:${cellIndex(rowShiftEnd, columnShiftEnd)})"
}

Formula refundFormula() {
    return new Formula(cellIndex(2, 0) + "+" + cellIndex(3, 0)
                    + "+" + cellIndex(4, 0)  + "-" + cellIndex(5, 0))
}

Formula commissionFormula() {
    return new Formula(cellIndex(2, 0) + "+" + cellIndex(3, 0) + "-" + cellIndex(4, 0))
}

Formula totalFormula() {
    return new Formula(cellIndex(-26, 0) + "+" + cellIndex(-21, 0)
            + "-" + cellIndex(-15, 0) + "-" + cellIndex(-9, 0)
            + "+" + cellIndex(-8, 0) + "-" + cellIndex(-7, 0)
            + "-" + cellIndex(-6, 0))
}

Formula balanceFormula() {
    return new Formula(cellIndex(-30, 0) + "+" + cellIndex(-3, 0) + "-" + cellIndex(-1, 0))
}

def fillCell(Object value, String style) {
    if (value == null) {
        value == ""
    }

    if (value instanceof Number) {
        number(value, style)
    } else if (value instanceof Date) {
        date(value, style)
    } else if (value instanceof Formula){
        formula(value.formula, style)
    } else {
        text(value, style)
    }

    nextColumn()
}

def printHeader() {
    rowHeight(15)
    text("РАСЧЕТНОЕ ПИСЬМО", "center-bold", 6, 1)
    nextRow()
    text("Агента по продаже пассажирских авиаперевозок на бланках ТКП", "center-bold", 6, 1)

    nextRow()
    nextRow()
    text("Авиакомпания: АО \"ИрАэро\"", "left", 6, 1)

    nextRow()
    text("Страна: РФ", "left", 6, 1)

    nextRow()
    text("Агент: " + parameters['AGENCY_NAME'], "left", 6, 1)

    DateFormatSymbols dfs = new DateFormatSymbols(LocaleManager.get().getCurrentLocale())
    String[] months = ["января", "февраля", "марта", "апреля",
                       "мая", "июня", "июля", "августа",
                       "сентября", "октября", "ноября", "декабря"]
    dfs.setMonths(months)
    SimpleDateFormat sdf = new SimpleDateFormat("\"dd\" MMMM yyyy г.", dfs);

    String agencyAgreementNumber = parameters['agency_agreement_number']
    Date agencyAgreementDate = (Date) parameters['agency_agreement_date']

    nextRow()
    text("Агентское соглашение № " +
            (TextUtil.nonBlank(agencyAgreementNumber) ? agencyAgreementNumber : "_______________") +
            " от " +
            (agencyAgreementDate ? sdf.format(agencyAgreementDate) : "________")
            , "left", 6, 1)

    def periodBeginParameter = parameters['key-report-params']?.periodBegin
    def periodEndParameter = parameters['key-report-params']?.periodEnd

    nextRow()
    nextRow()
    text("Отчетный период с " +
            (periodBeginParameter ? sdf.format(periodBeginParameter) : "") +
            " по " +
            (periodEndParameter ? sdf.format(periodEndParameter) : ""),
            "left", 6, 1)
}

def printTable() {
    printTableHeader()
    printTableBody()
}

def printTableHeader() {
    rowHeight(15);nextRow();nextRow()

    columnWidth(8);text('№ п/п', 'center-center-border');
    nextColumn();columnWidth(65);text('Раздел', 'center-center-border')
    nextColumn();columnWidth(17);text('Всего', 'center-center-border')
    nextColumn();columnWidth(17);text('МВЛ', 'center-center-border')
    nextColumn();columnWidth(17);text('ВВЛ', 'center-center-border')
    nextColumn();columnWidth(17);text('ВВЛ ДВФО', 'center-center-border')
}

def printTableBody() {
    Map<TransportationType, List<AirTicketsTemplateReportTicket>> tickets = collectTicketsByTransportationType()

    SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yy г.");
    def periodBeginParameter = parameters['key-report-params']?.periodBegin
    def periodEndParameter = parameters['key-report-params']?.periodEnd
    String periodBegin = periodBeginParameter ? sdf.format(periodBeginParameter) : ""
    String periodEnd = periodEndParameter ? sdf.format(periodEndParameter) : ""

    def mvlValues = makeCalculation(tickets.get(RouteType.INTERNATIONAL))
    def vvlValues = makeCalculation(tickets.get(RouteType.DOMESTIC))
    def dvfoValues = makeCalculation(tickets.get(RouteType.DVFO))

    nextRow()
    fillCell('', 'left-bold-border')
    fillCell('Сальдо взаиморасчетов на ' + periodBegin + ' в пользу Авиакомпании', 'left-bold-border')
    fillCell(sumRow(), 'right-bold-border-number')
    fillCell('', 'right-bold-border-number')
    fillCell('', 'right-bold-border-number')
    fillCell('', 'right-bold-border-number')

    nextRow()
    fillCell('1.', 'left-bold-border');
    fillCell('Выручка по реестрам продажи авиабилетов', 'left-bold-border')
    fillCell(sumRow(), 'right-bold-border-number')
    fillCell(columnRow(2, 4), 'right-bold-border-number')
    fillCell(columnRow(2, 4), 'right-bold-border-number')
    fillCell(columnRow(2, 4), 'right-bold-border-number')

    nextRow()
    fillCell('', 'left-border')
    fillCell('(1=1.1+1.2+1.3)', 'left-border')
    fillCell('', 'right-border-number')
    fillCell('', 'right-border-number')
    fillCell('', 'right-border-number')
    fillCell('', 'right-border-number')

    nextRow()
    fillCell('1.1.', 'left-border')
    fillCell('Тариф', 'left-border')
    fillCell(sumRow(), 'right-border-number')
    fillCell(mvlValues.get(0), 'right-border-number')
    fillCell(vvlValues.get(0), 'right-border-number')
    fillCell(dvfoValues.get(0), 'right-border-number')

    nextRow()
    fillCell('1.2.', 'left-border')
    fillCell('Такса за бланк (RU)', 'left-border')
    fillCell(sumRow(), 'right-border-number')
    fillCell(mvlValues.get(1), 'right-border-number')
    fillCell(vvlValues.get(1), 'right-border-number')
    fillCell(dvfoValues.get(1), 'right-border-number')

    nextRow()
    fillCell('1.3.', 'left-border')
    fillCell('Такса АГС (YQ)', 'left-border')
    fillCell(sumRow(), 'right-border-number')
    fillCell(mvlValues.get(2), 'right-border-number')
    fillCell(vvlValues.get(2), 'right-border-number')
    fillCell(dvfoValues.get(2), 'right-border-number')

    nextRow()
    fillCell('2.', 'left-bold-border');
    fillCell('Выручка по реестрам обмена авиабилетов', 'left-bold-border')
    fillCell(sumRow(), 'right-bold-border-number')
    fillCell(columnRow(2, 5), 'right-bold-border-number')
    fillCell(columnRow(2, 5), 'right-bold-border-number')
    fillCell(columnRow(2, 5), 'right-bold-border-number')

    nextRow()
    fillCell('', 'left-border')
    fillCell('(2=2.1+2.2+2.3+2.4)', 'left-border')
    fillCell('', 'right-border-number')
    fillCell('', 'right-border-number')
    fillCell('', 'right-border-number')
    fillCell('', 'right-border-number')

    nextRow()
    fillCell('2.1.', 'left-border')
    fillCell('Тариф', 'left-border')
    fillCell(sumRow(), 'right-border-number')
    fillCell(mvlValues.get(3), 'right-border-number')
    fillCell(vvlValues.get(3), 'right-border-number')
    fillCell(dvfoValues.get(3), 'right-border-number')

    nextRow()
    fillCell('2.2.', 'left-border')
    fillCell('Такса за бланк (RU)', 'left-border')
    fillCell(sumRow(), 'right-border-number')
    fillCell(mvlValues.get(4), 'right-border-number')
    fillCell(vvlValues.get(4), 'right-border-number')
    fillCell(dvfoValues.get(4), 'right-border-number')

    nextRow()
    fillCell('2.3.', 'left-border')
    fillCell('Доплата по таксе АГС (YQ)', 'left-border')
    fillCell(sumRow(), 'right-border-number')
    fillCell(mvlValues.get(5), 'right-border-number')
    fillCell(vvlValues.get(5), 'right-border-number')
    fillCell(dvfoValues.get(5), 'right-border-number')

    nextRow()
    fillCell('2.4.', 'left-border')
    fillCell('Штраф', 'left-border')
    fillCell(sumRow(), 'right-border-number')
    fillCell(mvlValues.get(6), 'right-border-number')
    fillCell(vvlValues.get(6), 'right-border-number')
    fillCell(dvfoValues.get(6), 'right-border-number')

    nextRow()
    fillCell('3.', 'left-bold-border');
    fillCell('Возврат', 'left-bold-border')
    fillCell(sumRow(), 'right-bold-border-number')
    fillCell(refundFormula(), 'right-bold-border-number')
    fillCell(refundFormula(), 'right-bold-border-number')
    fillCell(refundFormula(), 'right-bold-border-number')

    nextRow()
    fillCell('', 'left-border')
    fillCell('(3=3.1+3.2+3.3-3.4)', 'left-border')
    fillCell('', 'right-border-number')
    fillCell('', 'right-border-number')
    fillCell('', 'right-border-number')
    fillCell('', 'right-border-number')

    nextRow()
    fillCell('3.1.', 'left-border')
    fillCell('Тариф', 'left-border')
    fillCell(sumRow(), 'right-border-number')
    fillCell(mvlValues.get(7), 'right-border-number')
    fillCell(vvlValues.get(7), 'right-border-number')
    fillCell(dvfoValues.get(7), 'right-border-number')

    nextRow()
    fillCell('3.2.', 'left-border')
    fillCell('Такса за бланк (RU)', 'left-border')
    fillCell(sumRow(), 'right-border-number')
    fillCell(mvlValues.get(8), 'right-border-number')
    fillCell(vvlValues.get(8), 'right-border-number')
    fillCell(dvfoValues.get(8), 'right-border-number')

    nextRow()
    fillCell('3.3.', 'left-border')
    fillCell('Такса АГС (YQ)', 'left-border')
    fillCell(sumRow(), 'right-border-number')
    fillCell(mvlValues.get(9), 'right-border-number')
    fillCell(vvlValues.get(9), 'right-border-number')
    fillCell(dvfoValues.get(9), 'right-border-number')

    nextRow()
    fillCell('3.4.', 'left-border')
    fillCell('Штраф', 'left-border')
    fillCell(sumRow(), 'right-border-number')
    fillCell(mvlValues.get(10), 'right-border-number')
    fillCell(vvlValues.get(10), 'right-border-number')
    fillCell(dvfoValues.get(10), 'right-border-number')

    nextRow()
    fillCell('4.', 'left-bold-border');
    fillCell('Продажа по ВПД', 'left-bold-border')
    fillCell(sumRow(), 'right-bold-border-number')
    fillCell(mvlValues.get(11), 'right-bold-border-number')
    fillCell(vvlValues.get(11), 'right-bold-border-number')
    fillCell(dvfoValues.get(11), 'right-bold-border-number')

    nextRow()
    fillCell('5.', 'left-bold-border');
    fillCell('Возврат по ВПД', 'left-bold-border')
    fillCell(sumRow(), 'right-bold-border-number')
    fillCell(mvlValues.get(12), 'right-bold-border-number')
    fillCell(vvlValues.get(12), 'right-bold-border-number')
    fillCell(dvfoValues.get(12), 'right-bold-border-number')

    nextRow()
    fillCell('6.', 'left-bold-border');
    fillCell('Продажа по ПК', 'left-bold-border')
    fillCell(sumRow(), 'right-bold-border-number')
    fillCell(mvlValues.get(13), 'right-bold-border-number')
    fillCell(vvlValues.get(13), 'right-bold-border-number')
    fillCell(dvfoValues.get(13), 'right-bold-border-number')

    nextRow()
    fillCell('7.', 'left-bold-border');
    fillCell('Комиссионное вознаграждение', 'left-bold-border')
    fillCell(sumRow(), 'right-bold-border-number')
    fillCell(commissionFormula(), 'right-bold-border-number')
    fillCell(commissionFormula(), 'right-bold-border-number')
    fillCell(commissionFormula(), 'right-bold-border-number')

    nextRow()
    fillCell('', 'left-border')
    fillCell('(7=7.1+7.2-7.3)', 'left-border')
    fillCell('', 'right-border-number')
    fillCell('', 'right-border-number')
    fillCell('', 'right-border-number')
    fillCell('', 'right-border-number')

    nextRow()
    fillCell('7.1.', 'left-border')
    fillCell('По реестрам продажи', 'left-border')
    fillCell(sumRow(), 'right-border-number')
    fillCell(mvlValues.get(14), 'right-border-number')
    fillCell(vvlValues.get(14), 'right-border-number')
    fillCell(dvfoValues.get(14), 'right-border-number')

    nextRow()
    fillCell('7.2.', 'left-border')
    fillCell('По реестрам обмена', 'left-border')
    fillCell(sumRow(), 'right-border-number')
    fillCell(mvlValues.get(15), 'right-border-number')
    fillCell(vvlValues.get(15), 'right-border-number')
    fillCell(dvfoValues.get(15), 'right-border-number')

    nextRow()
    fillCell('7.3.', 'left-border')
    fillCell('По реестрам возврата', 'left-border')
    fillCell(sumRow(), 'right-border-number')
    fillCell(mvlValues.get(16), 'right-border-number')
    fillCell(vvlValues.get(16), 'right-border-number')
    fillCell(dvfoValues.get(16), 'right-border-number')

    nextRow()
    fillCell('8.', 'left-bold-border');
    fillCell('ИТОГО подлежит перечислению авиакомпании', 'left-bold-border')
    fillCell('', 'right-border-number')
    fillCell('', 'right-border-number')
    fillCell('', 'right-border-number')
    fillCell('', 'right-border-number')

    nextRow()
    fillCell('', 'left-border')
    fillCell('(8=1+2-3-4+5-6-7)', 'left-border')
    fillCell(sumRow(), 'right-bold-border-number')
    fillCell(totalFormula(), 'right-bold-border-number')
    fillCell(totalFormula(), 'right-bold-border-number')
    fillCell(totalFormula(), 'right-bold-border-number')

    nextRow()
    fillCell('9.', 'left-bold-border');
    fillCell('Перечислено: № и дата платежного поручения', 'left-bold-border')
    fillCell('', 'right-bold-border-number')
    fillCell('', 'right-bold-border-number')
    fillCell('', 'right-bold-border-number')
    fillCell('', 'right-bold-border-number')

    nextRow()
    fillCell('10.', 'left-bold-border');
    fillCell('ИТОГО перечислено:', 'left-bold-border')
    fillCell(sumRow(), 'right-bold-border-number')
    fillCell('', 'right-bold-border-number')
    fillCell('', 'right-bold-border-number')
    fillCell('', 'right-bold-border-number')

    nextRow()
    fillCell('', 'left-bold-border')
    fillCell('Сальдо взаиморасчетов на ' + periodEnd + ' в пользу Авиакомпании', 'left-bold-border')
    fillCell(sumRow(), 'right-bold-border-number')
    fillCell(balanceFormula(), 'right-bold-border-number')
    fillCell(balanceFormula(), 'right-bold-border-number')
    fillCell(balanceFormula(), 'right-bold-border-number')
}

def makeCalculation(List<AirTicketsTemplateReportTicket> list) {
    def result = []

    def sellFare = BigDecimal.ZERO
    def sellRuTax = BigDecimal.ZERO
    def sellYqTax = BigDecimal.ZERO

    def exchangeFare = BigDecimal.ZERO
    def exchangeRuTax = BigDecimal.ZERO
    def exchangeYqTax = BigDecimal.ZERO
    def exchangePenalty = BigDecimal.ZERO

    def refundFare = BigDecimal.ZERO
    def refundRuTax = BigDecimal.ZERO
    def refundYqTax = BigDecimal.ZERO
    def refundPenalty = BigDecimal.ZERO

    def sellMtd = BigDecimal.ZERO
    def refundMtd = BigDecimal.ZERO
    def sellPk = BigDecimal.ZERO

    def sellCommission = BigDecimal.ZERO
    def exchangeCommission = BigDecimal.ZERO
    def refundCommission = BigDecimal.ZERO

    list.each { AirTicketsTemplateReportTicket ticket ->
        if (ticket.operationBatch != null) {
            def ruTax = BigDecimal.ZERO
            def yqTax = BigDecimal.ZERO
            ticket.taxes.each { Tax tax ->
                if ('RU'.equals(tax.code) && (tax.equivalentAmount != null)){
                    ruTax = MiscUtil.sum(ruTax, tax.equivalentAmount)
                } else if ('YQ'.equals(tax.code) && (tax.equivalentAmount != null)){
                    yqTax = MiscUtil.sum(yqTax, tax.equivalentAmount)
                }
            }

            switch (ticket.operationBatch) {
                case OperationBatch.SELL:
                    if (ticket.mcoCategory == MCOCategory.REBOOKING) {
                        exchangePenalty = MiscUtil.sum(exchangePenalty, ticket.price)
                    } else {
                        sellFare = MiscUtil.sum(sellFare, ticket.equivalentFare)
                        sellRuTax = MiscUtil.sum(sellRuTax, ruTax)
                        sellYqTax = MiscUtil.sum(sellYqTax, yqTax)

                        if (ticket.paymentTypes.contains(PaymentType.MTD)
                                || ticket.paymentTypes.contains(PaymentType.CREDIT)) {
                            sellMtd = MiscUtil.sum(sellMtd, ticket.price)
                        } else if (ticket.paymentTypes.contains(PaymentType.CREDIT_CARD)) {
                            sellPk = MiscUtil.sum(sellPk, ticket.price)
                            ticket.taxes.each { Tax tax ->
                                if ('ZZ'.equals(tax.code) && (tax.equivalentAmount != null)){
                                    sellPk = MiscUtil.sub(sellPk, tax.equivalentAmount)
                                }
                            }
                        }
                    }

                    sellCommission = MiscUtil.sum(sellCommission, ticket.vendorCommissionValue)

                    break
                case OperationBatch.EXCHANGE:
                    if (ticket.mcoCategory == MCOCategory.REBOOKING) {
                        exchangePenalty = MiscUtil.sum(exchangePenalty, ticket.price)
                    } else {
                        exchangeFare = MiscUtil.sum(exchangeFare, ticket.equivalentFare)
                        exchangeRuTax = MiscUtil.sum(exchangeRuTax, ruTax)
                        exchangeYqTax = MiscUtil.sum(exchangeYqTax, yqTax)
                        exchangePenalty = MiscUtil.sum(exchangePenalty, ticket.penalty)

                        if (ticket.paymentTypes.contains(PaymentType.MTD)
                                || ticket.paymentTypes.contains(PaymentType.CREDIT)) {
                            sellMtd = MiscUtil.sum(sellMtd, ticket.price)
                        }
                    }

                    exchangeCommission = MiscUtil.sum(exchangeCommission, ticket.vendorCommissionValue)

                    break
                case OperationBatch.REFUND:
                    if (ticket.mcoCategory == MCOCategory.REBOOKING) {
                        exchangePenalty = MiscUtil.sub(exchangePenalty, ticket.price)
                    } else {
                        refundFare = MiscUtil.sum(refundFare, ticket.equivalentFare)
                        refundRuTax = MiscUtil.sum(refundRuTax, ruTax)
                        refundYqTax = MiscUtil.sum(refundYqTax, yqTax)
                        refundPenalty = MiscUtil.sum(refundPenalty, ticket.penalty)

                        if (ticket.paymentTypes.contains(PaymentType.MTD)
                                || ticket.paymentTypes.contains(PaymentType.CREDIT)) {
                            refundMtd = MiscUtil.sum(refundMtd, ticket.price)
                        }
                    }

                    refundCommission = MiscUtil.sum(refundCommission, ticket.vendorCommissionValue)

                    break
            }
        }
    }

    result.add(sellFare)           //0
    result.add(sellRuTax)          //1
    result.add(sellYqTax)          //2

    result.add(exchangeFare)       //3
    result.add(exchangeRuTax)      //4
    result.add(exchangeYqTax)      //5
    result.add(exchangePenalty)    //6

    result.add(refundFare)         //7
    result.add(refundRuTax)        //8
    result.add(refundYqTax)        //9
    result.add(refundPenalty)      //10

    result.add(sellMtd)            //11
    result.add(refundMtd)          //12
    result.add(sellPk)             //13

    result.add(sellCommission)     //14
    result.add(exchangeCommission) //15
    result.add(refundCommission)   //16

    return result
}

def collectTicketsByTransportationType() {
    Map<RouteType, List<AirTicketsTemplateReportTicket>> result = new HashMap<>()
    result.put(RouteType.DOMESTIC, new ArrayList<AirTicketsTemplateReportTicket>())
    result.put(RouteType.INTERNATIONAL, new ArrayList<AirTicketsTemplateReportTicket>())
    result.put(RouteType.DVFO, new ArrayList<AirTicketsTemplateReportTicket>())

    tickets { AirTicketsTemplateReportTicket ticket ->
        if (ticket.isRouteContainsDVFO()){
            result.get(RouteType.DVFO).add(ticket)
        } else if (TransportationType.DOMESTIC == ticket.transportationType) {
            result.get(RouteType.DOMESTIC).add(ticket)
        } else if (TransportationType.INTERNATIONAL == ticket.transportationType) {
            result.get(RouteType.INTERNATIONAL).add(ticket)
        }
    }

    return result
}

def printAccountant() {
    EntityReference<Person> accountantRef = (EntityReference<Person>) parameters['report_author']
    EntityContainer<Person> accountantCont = EntityStorage.get().resolve(accountantRef)

    String accountantName =
            accountantCont ? PersonalLocalizableNameUtil.buildFullName(
                    accountantCont.entity, true, LocaleHelper.RU_LOCALE, false) : "___________"

    nextRow(); rowHeight(30); nextRow(); nextColumn(); rowHeight(30)
    text("Бухгалтер:  ____________________ (" + accountantName + ")" +
            "\n" + "М.П.", "left", 2, 1)
}

page{'Расчетное письмо'} {
    fitWidth(1)
    fitHeight(1)
    landscape(false)

    printHeader()
    printTable()
    printAccountant()
}

enum RouteType {
    INTERNATIONAL,
    DOMESTIC,
    DVFO
}