//IMPORT

import com.gridnine.xtrip.common.model.booking.agencymemo.AgencyMemoProductType
import com.gridnine.xtrip.common.model.system.PaymentType
import com.gridnine.xtrip.common.reports.model.AirTicketsTemplateReportTicket
import com.gridnine.xtrip.common.reports.model.AirTicketsTemplateReportTicketType
import com.gridnine.xtrip.common.util.MiscUtil
import com.gridnine.xtrip.common.model.booking.ProductStatus

//CREATING STYLES
createStyle(name: 'title',fontBold: true, h_span: 18, h_alignment: 'CENTER', v_alignment: 'CENTER', fontHeight:15)
createStyle(name: 'header',fontBold: false,  h_alignment: 'CENTER', v_alignment: 'CENTER', fontHeight:10, leftBorder:'MEDIUM', rightBorder:'MEDIUM', topBorder:'MEDIUM', bottomBorder:'MEDIUM', wrapText: true)
createStyle(name: 'data',fontBold: false,  h_alignment: 'CENTER', v_alignment: 'CENTER', fontHeight:10, leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN', format: '#,##0.00')
createStyle(name: 'textData',parent: 'data')
createStyle(name: 'redtextData',parent: 'data', fontColor:'RED')
createStyle(name: 'numberData',parent: 'data',h_alignment: 'RIGHT', format: '#,##0.00')
createStyle(name: 'subtextData',fontBold: false,  h_alignment: 'RIGHT', v_alignment: 'CENTER', fontHeight:10, fontItalic: true)
createStyle(name: 'subData',parent: 'subtextData', format: '#,##0.00')
createStyle(name: 'dateData',parent: 'data',h_alignment: 'RIGHT',format: 'm/d/yy')
createStyle(name: 'subtotalTitle', parent: 'header', h_span: 7, h_alignment: 'RIGHT', fontBold: true)
createStyle(name: 'subtotalNumber',parent: 'subtotalTitle',  h_span: 1, format: '#,##0.00')
createStyle(name: 'totalTitle', parent: 'subtotalTitle', h_span: 3)
createStyle(name: 'totalNumber',parent: 'totalTitle', format: '#,##0.00')
createStyle(name: 'titleH2', fontHeight: 9, h_alignment: 'CENTER', v_alignment: 'CENTER')
createStyle(name: 'titleH3', fontHeight: 7, h_alignment: 'CENTER', v_alignment: 'CENTER')
createStyle(name: 'ahl', h_alignment: 'LEFT')
createStyle(name: 'bb', bottomBorder: 'THIN')

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

    if (ticket.type != AirTicketsTemplateReportTicketType.MEMO) {
        result = ticket.equivalentFare ? ticket.equivalentFare : BigDecimal.ZERO
        if (ticket.status == ProductStatus.REFUND || ticket.status == ProductStatus.EXCHANGE) {
            result = result.negate()
        }
    } else {
        result = ticket.agencyMemoProductTariffEquivalentAmount ? ticket.agencyMemoProductTariffEquivalentAmount : BigDecimal.ZERO
        if (ticket.agencyMemoProductType == AgencyMemoProductType.ACM) {
            result = result.negate()
        }
    }

    return result
}
def taxes = { AirTicketsTemplateReportTicket ticket ->
    BigDecimal result

    if (ticket.type != AirTicketsTemplateReportTicketType.MEMO) {
        result = ticket.taxesSum ? ticket.taxesSum : BigDecimal.ZERO
        if (ticket.status == ProductStatus.REFUND || ticket.status == ProductStatus.EXCHANGE) {
            result = result.negate()
        }
    } else {
        result = sum(ticket.agencyMemoProductTaxesCarrierEquivalentAmount, ticket.agencyMemoProductTaxesFuelEquivalentAmount,
                ticket.agencyMemoProductTaxesStateEquivalentAmount, ticket.agencyMemoProductTaxesOthersEquivalentAmount)
        if (ticket.agencyMemoProductType == AgencyMemoProductType.ACM) {
            result = result.negate()
        }
    }

    return result
}
def penalty =  { AirTicketsTemplateReportTicket ticket ->
    BigDecimal result

    if (ticket.type != AirTicketsTemplateReportTicketType.MEMO) {
        result = ticket.penalty ? ticket.penalty : BigDecimal.ZERO
    } else {
        result = sum(ticket.agencyMemoProductPenaltyEquivalentAmount, ticket.agencyMemoProductContractPenaltyEquivalentAmount)
        if (ticket.agencyMemoProductType == AgencyMemoProductType.ACM) {
            result = result.negate()
        }
    }

    return result
}
def total = { AirTicketsTemplateReportTicket ticket ->
    return taxes(ticket).add(fare(ticket)).add(penalty(ticket))
}
def agencyMemoCommissionAmount = { AirTicketsTemplateReportTicket ticket ->
    BigDecimal commissionAndBonus = sum(ticket.agencyMemoProductCommissionEquivalentAmount, ticket.agencyMemoProductBonusEquivalentAmount)
    BigDecimal fee = ticket.agencyMemoProductFeeEquivalentAmount ? ticket.agencyMemoProductFeeEquivalentAmount : BigDecimal.ZERO
    if (ticket.agencyMemoProductType == AgencyMemoProductType.ACM) {
        fee = fee.negate()
    } else {
        commissionAndBonus = commissionAndBonus.negate()
    }

    return commissionAndBonus.add(fee)
}
def bspCommissionAmount = { AirTicketsTemplateReportTicket ticket ->
    BigDecimal result

    if (ticket.type != AirTicketsTemplateReportTicketType.MEMO) {
        result = ticket.bspCommissionEquivalentAmount ? ticket.bspCommissionEquivalentAmount : BigDecimal.ZERO
        if (ticket.status == ProductStatus.REFUND || ticket.status == ProductStatus.EXCHANGE) {
            result = result.negate()
        }
    } else {
        result = agencyMemoCommissionAmount(ticket)
    }

    if (MiscUtil.isZero(result, false)) {
        result = null
    }

    return result
}
def gdsBspCommissionAmount = { AirTicketsTemplateReportTicket ticket ->
    BigDecimal result

    if (ticket.type != AirTicketsTemplateReportTicketType.MEMO) {
        result = ticket.gdsBspCommissionEquivalentAmount ? ticket.gdsBspCommissionEquivalentAmount : BigDecimal.ZERO
        if (ticket.status == ProductStatus.REFUND || ticket.status == ProductStatus.EXCHANGE) {
            result = result.negate()
        }
    } else {
        result = agencyMemoCommissionAmount(ticket)
    }

    if (MiscUtil.isZero(result, false)) {
        result = null
    }

    return result
}
def fops =  {def it->

    StringBuilder b = new StringBuilder()

    for(Object fop : it.paymentTypes) {

        if(b.length() != 0) {
            b.append(", ")
        }

        if(fop) {
            b.append(fop.toString())
        }
    }

    return b.toString()
}


//REPORT
page{it.transportationType?.name()}{
    //TITLE
    rowHeight(30)
    setStyle('title')
    text("Отчет о забронированных и оформленных авиабилетах (ВВЛ) за период ${parameters.REPORT_PERIOD}")
    //HEADER
    setStyle('normal')
    nextRow()
    rowHeight(15)
    nextRow()
    rowHeight(60)
    setStyle('header')
    text('Р/К валид.  п-ка')
    nextColumn()
    columnWidth(30)
    text('Валид. перевозчик')
    nextColumn()
    columnWidth(15)
    text('Форма оплаты')
    nextColumn()
    columnWidth(30)
    text('Маршрут')
    nextColumn()
    columnWidth(12)
    text('Номер билета')
    nextColumn()
    columnWidth(9)
    text('Статус')
    nextColumn()
    columnWidth(10)
    text('Дата выписки')
    nextColumn()
    columnWidth(10)
    text('Экв. тариф')
    nextColumn()
    columnWidth(10)
    text('Сумма такс')
    nextColumn()
    columnWidth(8)
    text('Штраф')
    nextColumn()
    columnWidth(10)
    text('Сумма общая')
    nextColumn()
    columnWidth(8)
    text('% ком. BSP')
    nextColumn()
    columnWidth(8)
    text('Сумма ком. BSP')
    nextColumn()
    columnWidth(8)
    text('% ком. BSP (GDS)')
    nextColumn()
    columnWidth(8)
    text('Сумма ком. BSP (GDS)')
    def summCells = []
    def commCells = []
    nextColumn()
    columnWidth(30)
    text('Пассажир')
    nextColumn()
    columnWidth(10)
    text('Дата вылета')
    nextColumn()
    columnWidth(10)
    text('PNR')

    //DATA
    groups{it.validatingCarrierNumber}{
        nextRow()
        String fareRow = cellIndex(0,7)
        String taxesRow = cellIndex(0,8)
        String penaltyRow = cellIndex(0,9)
        String totalRow = cellIndex(0,10)
        String bspRow = cellIndex(0,12)
        String gdsRow = cellIndex(0,14)
        tickets{ AirTicketsTemplateReportTicket ticket ->
            rowHeight(15)
            text(ticket.validatingCarrierNumber,'textData')
            nextColumn()
            text(ticket.validatingCarrier?.toString(),'textData')
            nextColumn()
            text(fops(ticket),'textData')
            nextColumn()
            text(ticket.routeLine,'textData')
            nextColumn()
            text(ticket.ticketNumber,'textData')
            nextColumn()
            text(ticket.status?.toString(), ticket.paymentTypes.contains(PaymentType.CREDIT_CARD) ? 'redtextData' : 'textData')
            nextColumn()
            date(ticket.issueDate,'dateData')
            nextColumn()
            number(ticket.paymentTypes.contains(PaymentType.CREDIT_CARD) ? BigDecimal.ZERO : fare(ticket),'numberData')
            nextColumn()
            number(ticket.paymentTypes.contains(PaymentType.CREDIT_CARD) ? BigDecimal.ZERO : taxes(ticket),'numberData')
            nextColumn()
            number(ticket.paymentTypes.contains(PaymentType.CREDIT_CARD) ? BigDecimal.ZERO : penalty(ticket),'numberData')
            nextColumn()
            number(ticket.paymentTypes.contains(PaymentType.CREDIT_CARD) ? BigDecimal.ZERO : total(ticket),'numberData')
            nextColumn()
            number(ticket.status == ProductStatus.REFUND || ticket.status == ProductStatus.EXCHANGE ? MiscUtil.negate(ticket.bspCommissionPercent) : ticket.bspCommissionPercent,'numberData')
            nextColumn()
            number(bspCommissionAmount(ticket),'numberData')
            nextColumn()
            number(ticket.status == ProductStatus.REFUND || ticket.status == ProductStatus.EXCHANGE ? MiscUtil.negate(ticket.gdsBspCommissionPercent) : ticket.gdsBspCommissionPercent,'numberData')
            nextColumn()
            number(gdsBspCommissionAmount(ticket),'numberData')
            nextColumn()
            text(ticket.travellerName,'textData')
            nextColumn()
            date(ticket.departureDate, 'dateData')
            nextColumn()
            text(ticket.pnr, 'textData')
            nextColumn()
            text(!bspCommissionAmount(ticket) || !gdsBspCommissionAmount(ticket) || bspCommissionAmount(ticket) != gdsBspCommissionAmount(ticket) ? 'commission difference' : null,'subData')
            nextRow()
        }
        //SUBTOTAL
        text('Итого','subtotalTitle')
        nextColumn()
        formula("SUM(${fareRow}:${cellIndex(-1,0)})",'subtotalNumber')
        nextColumn()
        formula("SUM(${taxesRow}:${cellIndex(-1,0)})",'subtotalNumber')
        nextColumn()
        formula("SUM(${penaltyRow}:${cellIndex(-1,0)})",'subtotalNumber')
        nextColumn()
        formula("SUM(${totalRow}:${cellIndex(-1,0)})",'subtotalNumber')
        summCells << cellIndex(0,0)
        commCells << cellIndex(0,4)
        nextColumn()
        number(null,'subtotalNumber')
        nextColumn()
        formula("SUM(${bspRow}:${cellIndex(-1,0)})",'subtotalNumber')
        nextColumn()
        number(null,'subtotalNumber')
        nextColumn()
        formula("SUM(${gdsRow}:${cellIndex(-1,0)})",'subtotalNumber')
        2.times{nextRow()}
        9.times{nextColumn()}
        text('К перечислению', 'subtextData')
        nextColumn()
        formula("${cellIndex(-2, 0)}-${cellIndex(-2, 4)}", 'subData')
        nextRow()
    }

    //TOTAL
    2.times{nextRow()}
    3.times{nextColumn()}
    text('Выручка', 'totalNumber')
    nextColumn()
    rowHeight(15)
    if(summCells.isEmpty()){
        number(BigDecimal.ZERO, 'totalNumber')
    } else{
    
        def formulaString = null
        
        summCells.each {
  
            if(formulaString != null){
                formulaString = formulaString + '+'
            }

            formulaString = formulaString ? formulaString + it : it
        }

        formula(formulaString, 'totalNumber')
    }

    nextRow()
    1.times{nextColumn()}
    text('Комиссионное вознаграждение', 'totalNumber')
    nextColumn()
    rowHeight(15)
    if(commCells.isEmpty()){
        number(BigDecimal.ZERO, 'totalNumber')
        
    } else {
    
        def formulaString = null
        
        commCells.each {
  
            if(formulaString != null){
                formulaString = formulaString + '+'
            }

            formulaString = formulaString ? formulaString + it : it
        }

        formula(formulaString, 'totalNumber')
    }
    
    
    nextRow()
    1.times{nextColumn()}
    text('К перечислению', 'totalNumber')
    nextColumn()
    formula("${cellIndex(-2, 0)}-${cellIndex(-1, 0)}", 'totalNumber')
}

4.times{nextRow()}
text('Руководитель', 'titleH2|ahl')
3.times{nextColumn()}
text(null, 'titleH2|bb', 2, 1)
3.times{nextColumn()}
text(null, 'titleH2|bb', 3, 1)
nextRow()
3.times{nextColumn()}
text('подпись', 'titleH3', 2, 1)
3.times{nextColumn()}
text('фамилия', 'titleH3', 3, 1)
2.times{nextRow()}

2.times{nextRow()}
text('Исполнитель', 'titleH2|ahl')
3.times{nextColumn()}
text(null, 'titleH2|bb', 2, 1)
3.times{nextColumn()}
text(null, 'titleH2|bb', 3, 1)
nextRow()
3.times{nextColumn()}
text('подпись', 'titleH3', 2, 1)
3.times{nextColumn()}
text('фамилия', 'titleH3', 3, 1)
2.times{nextRow()}