<?php

namespace Softsat\Locacao\Controller\Admin;

use Hwapx\Admin\Controller\Admin\Admin;
use Hwapx\Core\Library\Template;
use Hwapx\Core\Library\Validator;
use HwapX\Admin\Library\Builder\TableBuilder;
use HwapX\Admin\Library\Builder\FormBuilder;
use HwapX\Core\Library\DB\SQL\Mapper;

use SoftSAT\Locacao\Model\Contrato as ContratoModel;

class Contrato extends Admin {
    protected $validator = null;
    protected $logger    = null;
    protected $mapper    = null;
    protected $form = array(
        'name'   => 'Contrato',
        'table'  => 'softsat_locacao_admin_contrato_list',
        'depends'=> array(
            'softsat_locacao_boleto' => array(
                'name' => 'Boletos',
                'foreignkey' => 'contrato_id'
            ),
        ),
        'actions'=> array(
            'faturar' => array(
                'description' => 'Salvar e faturar',
                'class' => 'btn-success',
                'route' => 'javascript:$("[name=status]").val("F").trigger("change").parents("form").submit();'
            )
        ),
        'groups' => array(
            'contrato' => array(
                'legend' => 'Contrato',
                'fields' =>  array(
                    'a' => array(
                        'label' => 'Reserva',
                        'type' => 'separator'
                    ),
                    'cliente_id' => array(
                        'label' => 'Cliente',
                        'type'  => 'dropdown',
                        'options' => array(
                            '' => '-- Selecione --'
                        ),
                        'width' => 8,
                        'rules' => array(
                            'required',
                        ),
                    ),
                    'status' => array(
                        'label' => 'Status',
                        'type'  => 'dropdown',
                        'options' => array(
                            'A' => 'Aberto',
                            'F' => 'Faturado',
                            'C' => 'Cancelado',
                            'R' => 'Reserva',
                        ),
                        'width' => 4,
                    ),
                    'veiculo_id' => array(
                        'label' => 'Veículo',
                        'type'  => 'dropdown',
                        'options' => array(
                            '' => '-- Selecione --'
                        ),
                        'width' => 8,
                        'rules' => array(
                            'required',
                        ),
                    ),
                    'tarifa_id' => array(
                        'label'=> 'Tarifa',
                        'type' => 'dropdown',
                        'options' => array(
                            '' => '-- Selecione --'
                        ),
                        'width' => 4,
                        'rules' => array(
                            'required',
                        ),
                    ),
                    'saida' => array(
                        'label'  => 'Saída',
                        'type'   => 'datetime',
                        'format' => 'DD/MM/YYYY HH:mm:00',
                        'width'  => 3,
                        'rules' => array(
                            'required',
                            'datetime',
                        ),
                    ),
                    'previsto' => array(
                        'label'  => 'Entrada prevista',
                        'type'   => 'datetime',
                        'format' => 'DD/MM/YYYY HH:mm:00',
                        'width'  => 3,
                        'rules' => array(
                            'required',
                            'datetime',
                        ),
                    ),
                    'dias_previstos' => array(
                        'label'  => 'Dias previstos',
                        'type'   => 'text',
                        'width'  => 2,
                        'attributes' => array(
                            'id' => 'dias_previstos',
                            'style' => 'text-align: right',
                            'readonly' => 'readonly',
                        ),
                    ),
                    'diaria' => array(
                        'label'  => 'Diária',
                        'type'   => 'number',
                        'digits' => 2,
                        'width'  => 2,
                        'rules'  => array(
                            'required'
                        )
                    ),
                    'total_previsto' => array(
                        'label'  => 'Total previsto',
                        'type'   => 'number',
                        'width'  => 2,
                        'digits' => 2,
                        'attributes' => array(
                            'id' => 'total_previsto',
                            'style' => 'text-align: right',
                            'readonly' => 'readonly',
                        ),
                    ),
                    'local_saida_id' => array(
                        'label' => 'Local de saída',
                        'type'  => 'dropdown',
                        'options' => array(
                            '' => '-- Selecione --'
                        ),
                        'width' => 3,
                        'rules' => array(
                            'required',
                        ),
                    ),
                    'local_entrada_id' => array(
                        'label' => 'Local de entrada',
                        'type'  => 'dropdown',
                        'options' => array(
                            '' => '-- Selecione --'
                        ),
                        'width' => 3,
                        'rules' => array(
                            'required',
                        )
                    ),
                    'z' => array(
                        'label' => 'Abertura',
                        'type' => 'separator'
                    ),
                    'tanque_saida' => array(
                        'label'  => 'Tanque saída',
                        'type'   => 'text',
                        'width'  => 2,
                        'mask'   => '9/9',
                        'rules'  => array(
                            'lengthMax' => 3,
                        ),
                    ),
                    'km_saida' => array(
                        'label'  => 'KM Saída',
                        'type'   => 'number',
                        'digits' => 0,
                        'width'  => 2,
                        'rules'  => array(
                            'required',
                        ),
                    ),
                    'km_contratado' => array(
                        'label'  => 'KM Contratado',
                        'type'   => 'number',
                        'digits' => 0,
                        'width'  => 2,
                        'attributes' => array(
                            'style' => 'text-align: right',
                            'placeholder' => 'Livre'
                        )
                    ),
                    'forma_pagamento_id' => array(
                        'label' => 'Forma de pagamento',
                        'type'  => 'dropdown',
                        'options' => array(
                            '' => '-- Selecione --'
                        ),
                        'width' => 3,
                        'rules'  => array(
                            'required',
                            'boleto_nao_estrangeiro'
                        ),
                    ),
                    'condicao_pagamento_id' => array(
                        'label' => 'Condição de pagamento',
                        'type'  => 'dropdown',
                        'options' => array(
                            '' => '-- Selecione --'
                        ),
                        'width' => 3,
                        'rules'  => array(
                            'required',
                        ),
                    ),
                    'x' => array(
                        'label' => 'Faturamento',
                        'type' => 'separator'
                    ),
                    'tanque_entrada' => array(
                        'label'  => 'Tanque entrada',
                        'type'   => 'text',
                        'width'  => 2,
                        'mask'   => '9/9',
                        'rules'  => array(
                            'lengthMax' => 3,
                        ),
                    ),
                    'entrada' => array(
                        'label'  => 'Entrada',
                        'type'   => 'datetime',
                        'format' => 'DD/MM/YYYY HH:mm:00',
                        'width'  => 3,
                        'rules' => array(
                            'datetime',
                        ),
                    ),
                    'q' => array(
                        'type' => 'placeholder',
                        'width' => 7,
                    ),
                    'dias_utilizados' => array(
                        'label'  => 'Dias utilizados',
                        'type'   => 'text',
                        'width'  => 2,
                        'attributes' => array(
                            'id' => 'dias_utilizados',
                            'style' => 'text-align: right',
                            'readonly' => 'readonly',
                        ),
                    ),
                    'dias_cobrados' => array(
                        'label'  => 'Dias cobrados',
                        'type'   => 'text',
                        'width'  => 2,
                        'attributes' => array(
                            'id' => 'dias_cobrados',
                            'style' => 'text-align: right',
                            'readonly' => 'readonly',
                        ),
                    ),
                    'dias_excedidos' => array(
                        'label'  => 'Dias excedidos',
                        'type'   => 'text',
                        'width'  => 2,
                        'attributes' => array(
                            'id' => 'dias_excedidos',
                            'style' => 'text-align: right',
                            'readonly' => 'readonly',
                        ),
                    ),
                    'perc_multa_excedido' => array(
                        'label'  => '% Dias excedidos',
                        'type'   => 'number',
                        'width'  => 2,
                        'digits' => 2,
                        'attributes' => array(
                            'id' => 'perc_multa_excedido',
                            'style' => 'text-align: right',
                        ),
                    ),
                    'valor_multa_excedido' => array(
                        'label'  => 'Total Dias excedidos',
                        'type'   => 'number',
                        'width'  => 2,
                        'digits' => 2,
                        'attributes' => array(
                            'id' => 'valor_multa_excedido',
                            'style' => 'text-align: right',
                            'readonly' => 'readonly',
                        ),
                    ),
                    'total_dias' => array(
                        'label'  => 'Total dias',
                        'type'   => 'number',
                        'width'  => 2,
                        'digits' => 2,
                        'attributes' => array(
                            'id' => 'total_dias',
                            'style' => 'text-align: right',
                            'readonly' => 'readonly',
                        ),
                    ),
                    'km_entrada' => array(
                        'label'  => 'KM entrada',
                        'type'   => 'number',
                        'digits' => 0,
                        'width'  => 2,
                    ),
                    'km_excedido' => array(
                        'label'  => 'KM excedido',
                        'type'   => 'number',
                        'width'  => 2,
                        'digits' => 3,
                        'attributes' => array(
                            'id' => 'km_excedido',
                            'style' => 'text-align: right',
                            'readonly' => 'readonly',
                        ),
                    ),
                    'valor_km_excedido' => array(
                        'label'  => 'R$ KM excedido',
                        'type'   => 'number',
                        'width'  => 2,
                        'digits' => 2,
                    ),
                    'total_km_excedido' => array(
                        'label'  => 'Total KM excedido',
                        'type'   => 'number',
                        'width'  => 2,
                        'digits' => 2,
                        'attributes' => array(
                            'id' => 'total_km_excedido',
                            'style' => 'text-align: right',
                            'readonly' => 'readonly',
                        ),
                    ),
                    'y' => array(
                        'label'  => '',
                        'type'   => 'placeholder',
                        'width'  => 4,
                    ),
                    'subtotal' => array(
                        'label'  => 'Subtotal',
                        'type'   => 'number',
                        'width'  => 2,
                        'digits' => 2,
                        'attributes' => array(
                            'id' => 'subtotal',
                            'style' => 'text-align: right',
                            'readonly' => 'readonly',
                        ),
                    ),
                    'acrescimo_desconto' => array(
                        'label'  => 'Acréscimo/Desconto',
                        'type'   => 'number',
                        'width'  => 2,
                        'digits' => 2,
                    ),
                    'total' => array(
                        'label'  => 'Total',
                        'type'   => 'number',
                        'width'  => 2,
                        'digits' => 2,
                        'attributes' => array(
                            'id' => 'total',
                            'style' => 'text-align: right',
                            'readonly' => 'readonly',
                        ),
                    ),/*
                    't' => array(
                        'label'  => '',
                        'type'   => 'placeholder',
                        'width'  => 6,
                    ),
                    'total_diferenca' => array(
                        'label'  => 'Diferença',
                        'type'   => 'number',
                        'width'  => 2,
                        'digits' => 2,
                        'attributes' => array(
                            'id' => 'total_diferenca',
                            'style' => 'text-align: right',
                            'readonly' => 'readonly',
                        ),
                    ),
                    'fat_forma_pagamento_id' => array(
                        'label' => 'Forma de pagamento',
                        'type'  => 'dropdown',
                        'options' => array(
                            '' => '-- Selecione --'
                        ),
                        'width' => 3,
                        'rules'  => array(
                            //'required',
                            'boleto_nao_estrangeiro'
                        ),
                    ),
                    'fat_condicao_pagamento_id' => array(
                        'label' => 'Condição de pagamento',
                        'type'  => 'dropdown',
                        'options' => array(
                            '' => '-- Selecione --'
                        ),
                        'width' => 3,
                        'rules'  => array(
                            //'required',
                        ),
                    ),*/
                )
            ),
            'inf_adicionais' => array(
                'legend' => 'Informações Adicionais',
                'fields' => array(
                    'observacao' => array(
                        'label' => 'Observações',
                        'type'  => 'textarea',
                        'width' => 12
                    ),
                    'indenizacao_carro' => array(
                        'label'  => 'Indenização por custos Operacionais (Danos ao carro)',
                        'type'   => 'number',
                        'width'  => 6,
                        'digits' => 2,
                    ),
                    'indenizacao_terceiros' => array(
                        'label'  => 'Indenização por custos Operacionais (Danos a terceiros)',
                        'type'   => 'number',
                        'width'  => 6,
                        'digits' => 2,
                    ),
                )
            )
            /*
            'situacao_veiculo' => array(
                'legend' => 'Situação do veículo',
                'fields' =>  array(
                    'estado_frente' => array(
                        'label' => 'Frente',
                        'type'  => 'textarea',
                        'width' => 6,
                    ),
                    'estado_traseira' => array(
                        'label' => 'Traseira',
                        'type'  => 'textarea',
                        'width' => 6,
                    ),
                    'estado_direita' => array(
                        'label' => 'Direita',
                        'type'  => 'textarea',
                        'width' => 6,
                    ),
                    'estado_esquerda' => array(
                        'label' => 'Esquerda',
                        'type'  => 'textarea',
                        'width' => 6,
                    ),
                    'estado_superior' => array(
                        'label' => 'Superior',
                        'type'  => 'textarea',
                        'width' => 6,
                    ),
                    'estado_inferior' => array(
                        'label' => 'Inferior',
                        'type'  => 'textarea',
                        'width' => 6,
                    ),
                )
            )*/
        )
    );

    protected $table = array(
        'name'   => 'Contratos',
        'cols'   => array(
            'id'      => 'Código',
            'cliente' => 'Cliente',
            'veiculo_placa' => array(
                 'label' => 'Placa',
                 'mask' => '(AAA9A99)|(AAA-9999)',
                 'attributes' => array(
                     'data-inputmask-keepstatic' => 'true'
                 )
            ),
            'status_str' => array(
                'label'   => 'Status',
                'options' => array(
                    'R' => 'Reserva',
                    'A' => 'Aberto',
                    'F' => 'Faturado',
                    'C' => 'Cancelado',
                ),
            ),
        ),
        'actions' => array(
            array(
                'route'       => 'softsat_locacao_admin_contrato_create',
                'description' => 'Novo',
                'class'       => 'btn-primary',
                'role'        => 'softsat.locacao.contrato_create'
            )
        ),
        'rowactions' => array(
            array(
                'route'       => 'softsat_locacao_admin_contrato_edit',
                'description' => 'Alterar',
                'class'       => 'btn-primary',
                'default'     => true,
                'role'        => 'softsat.locacao.contrato_edit'
            ),
            array(
                'route'       => 'softsat_locacao_admin_contrato_remove',
                'description' => 'Remover',
                'class'       => 'btn-danger',
                'confirm'     => true,
                'role'        => 'softsat.locacao.contrato_remove'
            ),
            array(
                'route'       => 'softsat_locacao_admin_contrato_print',
                'description' => 'Contrato',
                'class'       => 'btn-default',
                'role'        => 'softsat.locacao.contrato_print'
            ),
            array(
                'route'       => 'softsat_locacao_admin_contrato_fatura_preview',
                'description' => 'Fatura',
                'class'       => 'btn-default',
                'role'        => 'softsat.locacao.contrato_fatura_print'
            ),
            array(
                'route'       => 'softsat_locacao_admin_contrato_boleto_preview',
                'description' => 'Boleto',
                'class'       => 'btn-default',
                'role'        => 'softsat.locacao.contrato_boleto_print'
            ),
            array(
                'route'       => 'softsat_locacao_admin_contrato_croqui_preview',
                'description' => 'Croqui',
                'class'       => 'btn-default',
                'role'        => 'softsat.locacao.contrato_croqui_print'
            ),
            array(
                'route'       => 'softsat_locacao_admin_contrato_checklist_preview',
                'description' => 'Checklist',
                'class'       => 'btn-default',
                'role'        => 'softsat.locacao.contrato_checklist_print'
            ),
        ),
        'rowcount' => true,
        'route'    => 'softsat_locacao_admin_contrato_list',
        'legend'   => array(
            'default' => 'Reserva',
            'info'    => 'Aberto',
            'warning' => 'Devolução em breve',
            'success' => 'Faturado',
            'danger'  => 'Cancelado'
        ),
    );

    public function __construct($f3) {
        parent::__construct($f3);

        $db           = $f3->get('db');
        $this->mapper = new Mapper($db, 'softsat_locacao_contrato');

        $mapper = new Mapper($db, 'softsat_locacao_cliente');

        foreach ($mapper->find() as $cliente) {
            $this->form['groups']['contrato']['fields']['cliente_id']['options'][$cliente->id] = "[{$cliente->cnpj_cpf}] {$cliente->nome}";
        }

        $mapper = new Mapper($db, 'softsat_locacao_veiculo');
        $mapper->grupo = "SELECT nome FROM softsat_locacao_grupo WHERE softsat_locacao_grupo.id = softsat_locacao_veiculo.grupo_id";
        $mapper->valor = "SELECT valor FROM softsat_locacao_tarifa WHERE softsat_locacao_tarifa.id = softsat_locacao_veiculo.tarifa_id";

        foreach ($mapper->find(array('inativado_em IS NULL OR inativado_em > CURRENT_DATE')) as $veiculo) {
            $this->form['groups']['contrato']['fields']['veiculo_id']['options'][$veiculo->id] = array(
                "label" => "[{$veiculo->placa}] {$veiculo->modelo} - {$veiculo->grupo}",
                "attributes" => array(
                    'data-tarifa_id' => $veiculo->tarifa_id,
                    'data-km_atual' => $veiculo->km_atual,
                    'data-indenizacao_carro' => $veiculo->indenizacao_carro,
                    'data-indenizacao_terceiros' => $veiculo->indenizacao_terceiros,
                ),
            );
        }

        $mapper = new Mapper($db, 'softsat_locacao_forma_pagamento');

        foreach ($mapper->find() as $forma) {
            $this->form['groups']['contrato']['fields']['forma_pagamento_id']['options'][$forma->id] = $forma->nome;
            //$this->form['groups']['contrato']['fields']['fat_forma_pagamento_id']['options'][$forma->id] = $forma->nome;
        }

        $mapper = new Mapper($db, 'softsat_locacao_condicao_pagamento');

        foreach ($mapper->find() as $condicao) {
            $this->form['groups']['contrato']['fields']['condicao_pagamento_id']['options'][$condicao->id] = $condicao->nome;
            //$this->form['groups']['contrato']['fields']['fat_condicao_pagamento_id']['options'][$condicao->id] = $condicao->nome;
        }

        $mapper = new Mapper($db, 'softsat_locacao_tarifa');

        foreach ($mapper->find() as $tarifa) {
            $this->form['groups']['contrato']['fields']['tarifa_id']['options'][$tarifa->id] =  array(
                "label" => "{$tarifa->nome} [" . number_format($tarifa->valor, 2, ',', '.') . "]",
                "attributes" => array('data-valor' => $tarifa->valor),
            );
        }

        $mapper = new Mapper($db, 'softsat_locacao_local');

        foreach ($mapper->find('ativo = 1') as $local) {
            $this->form['groups']['contrato']['fields']['local_saida_id']['options'][$local->id] = $local->nome;
        }

        $mapper = new Mapper($db, 'softsat_locacao_local');

        foreach ($mapper->find('ativo = 1') as $local) {
            $this->form['groups']['contrato']['fields']['local_entrada_id']['options'][$local->id] = $local->nome;
        }

        $this->form['groups']['contrato']['fields']['valor_km_excedido']['default'] = number_format($f3->get('settings.softsat.locacao.valor_km_excedido') / 100, 2, ',', '.');
    }

    public function index($f3) {
        $this->module->checkRole('softsat.locacao.contrato_list');

        $db           = $f3->get('db');
        $this->mapper = new Mapper($db, 'softsat_locacao_contrato_relatorio');

        $this->mapper->status_str = "CASE status WHEN 'R' THEN '   Reserva' WHEN 'F' THEN ' Faturado' WHEN 'A' THEN '  Aberto' WHEN 'C' THEN 'Cancelado' END";

        $this->table['rowcallback'] = function($mapper) {
            $data = array();

            switch($mapper->status) {
                case 'A':
                    $data['class'] = strtotime($mapper->previsto) <= strtotime('+1 day 23:59:59') ? 'warning' : 'info';
                    break;
                case 'F':
                    $data['class'] = 'success';
                    break;
                case 'C':
                    $data['class'] = 'danger';
                    break;
            }

            return $data;
        };

        echo TableBuilder::instance($this->mapper, $this->table)->render(null, null, array('order' => 'status_str ASC, id DESC'));
    }

    public function create($f3) {
        $this->module->checkRole('softsat.locacao.contrato_create');

        $this->form['groups']['contrato']['fields']['local_saida_id']['default']      = $f3->get('settings.softsat.locacao.contrato.local_saida_id');
        $this->form['groups']['contrato']['fields']['local_entrada_id']['default']    = $f3->get('settings.softsat.locacao.contrato.local_entrada_id');
        $this->form['groups']['contrato']['fields']['perc_multa_excedido']['default'] = $f3->get('settings.softsat.locacao.contrato.perc_multa_excedido');

        $this->appendScripts();
        $this->configurarValidacao();

        echo FormBuilder::instance($this->mapper, $this->form)->handle();
    }

    public function edit($f3) {
        $this->module->checkRole('softsat.locacao.contrato_edit');

        unset($this->form['groups']['contrato']['fields']['status']['options']['R']);

        $this->appendScripts();
        $this->configurarValidacao();

        $db = $f3->get('db');

        $form = FormBuilder::instance($this->mapper, $this->form);

        if($f3->get('VERB') == 'GET')
            $form->afterLoad(function($mapper) use($db) {
                $qtde_boletos = $db->exec('SELECT COUNT(1) AS qtde FROM softsat_locacao_boleto
                                            WHERE remessa_criacao IS NOT NULL AND cancelado = 0 AND contrato_id = ?', $mapper->id)[0]['qtde'];

                if($qtde_boletos > 0)
                    flash('warning', "Existem $qtde_boletos boletos gerados para esse contrato, a alteração do Cliente, Total Previsto, Data de saída, ".
                            "Forma de pagamento ou Condição de pagamento causará o cancelamento dos boletos existentes e a emissão de novos (O que pode resultar em encargos administrativos).");
            });

        echo $form->handle();
    }

    public function remove($f3) {
        $this->module->checkRole('softsat.locacao.contrato_remove');

        if($f3->get('VERB') == 'GET') {
            flash('warning', 'Para excluir o contrato <strong>'.$f3->get('PARAMS.id').'</strong> você precisa se autenticar novamente.');

            echo Template::instance()->render('softsat/locacao/contrato/auth.html');
            return;
        }

        $logger = new \Log(date('Y-m-d') . '_contrato.log');
        $db = $f3->get('db');

        $user = new \DB\SQL\Mapper($db, 'hwapx_user');
        $user->load(array('LOWER(email) = LOWER(?) AND active = 1', $f3->get('SESSION.admin.email')));

        if ($user->dry() || !\Bcrypt::instance()->verify($f3->get('POST.password'), $user->password)) {
            $logger->write('Falha na autenticação com o usuário "' . $f3->get('POST.email') . '" na área de exclusão de contrato.');

            flash('error', 'Senha incorreta.');

            $f3->reroute('@softsat_locacao_admin_contrato_remove');
            return;
        }

        $logger->write('Usuário "' . $f3->get('POST.email') . '" se autenticou e excluiu o contrato '.$f3->get('PARAMS.id'));

        echo FormBuilder::instance($this->mapper, $this->form)->delete();
    }

    public function preview($f3) {
        $this->module->checkRole('softsat.locacao.contrato_print');

        $db           = $f3->get('db');
        $this->mapper = new Mapper($db, 'softsat_locacao_contrato_relatorio');

        $data = array(
            'contrato' => $this->mapper->findone(array('id = ?', $f3->get('PARAMS.id')))
        );

        if(!$data['contrato'])
            $this->f3->error(404);

        echo Template::instance()->render('softsat/locacao/contrato/contrato-preview.html', null, $data);
    }

    public function pdf($f3) {
        $this->module->checkRole('softsat.locacao.contrato_print');

        $contrato = new ContratoModel($f3);
        $data     = $contrato->renderPdf($f3->get('PARAMS.id'));

        if(!$data) {
            $this->f3->error(404);
            return;
        }

        header('content-type: application/pdf');
        echo $data;
    }

    public function faturaPreview($f3) {
        $this->module->checkRole('softsat.locacao.contrato_fatura_print');

        $db           = $f3->get('db');
        $this->mapper = new Mapper($db, 'softsat_locacao_contrato_relatorio');

        $data = array(
            'contrato' => $this->mapper->findone(array('id = ?', $f3->get('PARAMS.id')))
        );

        if(!$data['contrato'])
            $this->f3->error(404);

        echo Template::instance()->render('softsat/locacao/contrato/fatura-preview.html', null, $data);
    }

    public function faturaPdf($f3) {
        $this->module->checkRole('softsat.locacao.contrato_fatura_print');

        $contrato = new ContratoModel($f3);
        $data     = $contrato->renderFaturaPdf($f3->get('PARAMS.id'));

        if(!$data) {
            $this->f3->error(404);
            return;
        }

        header('content-type: application/pdf');
        echo $data;
    }

    public function croquiPreview($f3) {
        $this->module->checkRole('softsat.locacao.contrato_croqui_print');

        $db           = $f3->get('db');
        $this->mapper = new Mapper($db, 'softsat_locacao_contrato_relatorio');

        $data = array(
            'contrato' => $this->mapper->findone(array('id = ?', $f3->get('PARAMS.id')))
        );

        if(!$data['contrato'])
            $this->f3->error(404);

        echo Template::instance()->render('softsat/locacao/contrato/croqui-preview.html', null, $data);
    }

    public function croquiPdf($f3) {
        $this->module->checkRole('softsat.locacao.contrato_croqui_print');

        $contrato = new ContratoModel($f3);
        $data     = $contrato->renderCroquiPdf($f3->get('PARAMS.id'));

        if(!$data) {
            $this->f3->error(404);
            return;
        }

        header('content-type: application/pdf');
        echo $data;
    }

    public function checklistPreview($f3) {
        $this->module->checkRole('softsat.locacao.contrato_checklist_print');

        $db           = $f3->get('db');
        $this->mapper = new Mapper($db, 'softsat_locacao_contrato_relatorio');

        $data = array(
            'contrato' => $this->mapper->findone(array('id = ?', $f3->get('PARAMS.id')))
        );

        if(!$data['contrato'])
            $this->f3->error(404);

        echo Template::instance()->render('softsat/locacao/contrato/checklist-preview.html', null, $data);
    }

    public function checklistPdf($f3) {
        $this->module->checkRole('softsat.locacao.contrato_checklist_print');

        $contrato = new ContratoModel($f3);
        $data     = $contrato->renderChecklistPdf($f3->get('PARAMS.id'));

        if(!$data) {
            $this->f3->error(404);
            return;
        }

        header('content-type: application/pdf');
        echo $data;
    }

    public function boletoPreview($f3) {
        $this->module->checkRole('softsat.locacao.contrato_boleto_print');

        $db           = $f3->get('db');
        $this->mapper = new Mapper($db, 'softsat_locacao_contrato_relatorio');
        $boletos      = new Mapper($db, 'softsat_locacao_boleto');

        $data = array(
            'contrato' => $this->mapper->findone(array('id = ?', $f3->get('PARAMS.id')))
        );

        if(!$data['contrato'])
            $this->f3->error(404);

        if(!$boletos->load(array('cancelado = 0 AND contrato_id = ?', $data['contrato']->id))) {
            flash('warning', 'O contrato selecionado não possui boletos');
            $f3->reroute($_SERVER['HTTP_REFERER']);
        }

        echo Template::instance()->render('softsat/locacao/contrato/boleto-preview.html', null, $data);
    }

    public function boletoPdf($f3) {
        $this->module->checkRole('softsat.locacao.contrato_boleto_print');

        $contrato = new ContratoModel($f3);
        $data     = $contrato->renderBoletoPdf($f3->get('PARAMS.id'));

        if(!$data) {
            $this->f3->error(404);
            return;
        }

        header('content-type: application/pdf');
        echo $data;
    }

    private function appendScripts() {
        $this->f3->set('meta.scripts.raw.diaria', '
        $(document).ready(function() {
            function calcularTotal() {
                var diaria = $("[name=diaria]").val() || "0";
                var acres_desc = $("[name=acrescimo_desconto]").val() || "0";
                var perc_multa = $("[name=perc_multa_excedido]").val() || "0";
                var dias_previstos = parseFloat($("#dias_previstos").val() || 0);
                var dias_cobrados  = parseFloat($("#dias_cobrados").val() || 0);
                var dias_excedidos = parseFloat($("#dias_excedidos").val() || 0);
                var km_excedido = $("#km_excedido").val() || "0";
                var valor_km = $("[name=valor_km_excedido]").val() || "0";

                diaria     = parseFloat(diaria.replace(".", "").replace(",", "."));
                acres_desc = parseFloat(acres_desc.replace(".", "").replace(",", "."));
                perc_multa = parseFloat(perc_multa.replace(".", "").replace(",", "."));
                km_excedido = parseFloat(km_excedido.replace(".", "").replace(",", "."));
                valor_km = parseFloat(valor_km.replace(".", "").replace(",", "."));

                if(dias_previstos < 1)
                    dias_previstos = 1;

                var multa    = parseFloat(dias_excedidos * diaria * (perc_multa > 0 ? perc_multa / 100.0 : 0));
                var multa_km = parseFloat(km_excedido * valor_km);
                var total_previsto = diaria * dias_previstos;

                $("#valor_multa_excedido").val(multa.toFixed(2));
                $("#total_km_excedido").val(multa_km.toFixed(2));
                $("#total_previsto").val(total_previsto.toFixed(2));

                var subtotal = (diaria * dias_cobrados) + multa + multa_km;

                $("#total_dias").val((diaria * dias_cobrados).toFixed(2));
                $("#subtotal").val(subtotal.toFixed(2));

                var total = subtotal + acres_desc;
                var diferenca = Math.max(total - total_previsto, 0);

                $("#total").val(total.toFixed(2));
                $("#total_diferenca").val(diferenca.toFixed(2));
            }

            $("[name=previsto], [name=saida], [name=entrada], [name=km_contratado], [name=km_entrada], [name=km_saida]").on("blur", function() {
                var saida = $("[name=saida]").parent().data("DateTimePicker").date();
                var previsto = $("[name=previsto]").parent().data("DateTimePicker").date();
                var entrada = $("[name=entrada]").parent().data("DateTimePicker").date();
                var km_entrada = $("[name=km_entrada]").val() || "0";
                var km_saida = $("[name=km_saida]").val() || "0";
                var km_contratado = $("[name=km_contratado]").val() || "0";

                km_entrada    = parseFloat(km_entrada.replace(".", "").replace(",", "."));
                km_saida      = parseFloat(km_saida.replace(".", "").replace(",", "."));
                km_contratado = parseFloat(km_contratado.replace(".", "").replace(",", "."));

                var dias_previstos  = saida && previsto ? previsto.diff(saida) / 1000 / 60 / 60 / 24 : 0;
                var dias_utilizados = saida && entrada ? entrada.diff(saida) / 1000 / 60 / 60 / 24 : 0;
                var dias_cobrados   = Math.max(dias_utilizados < dias_previstos && dias_utilizados % 1.0 > 0.5 ? Math.ceil(dias_utilizados) : dias_utilizados, 1);
                var dias_excedidos  = Math.max(dias_utilizados - dias_previstos, 0);
                var km_excedido     = 0;
                if(km_contratado > 0)
                    km_excedido = Math.max(km_entrada - km_contratado - km_saida, 0);

                $("#dias_previstos").val(dias_previstos);
                $("#dias_utilizados").val(dias_utilizados);
                $("#dias_cobrados").val(dias_cobrados);
                $("#dias_excedidos").val(dias_excedidos);
                $("#km_excedido").val(km_excedido.toFixed(3));

                calcularTotal();
            }).trigger("blur");

            $("[name=diaria], [name=acrescimo_desconto], [name=perc_multa_excedido], [name=km_excedido], [name=valor_km_excedido]").blur(calcularTotal);

            $("[name=veiculo_id]").change(function() {
                var $option   = $(this).find("option:selected");
                var tarifa_id = $option.data("tarifa_id") || "";
                var km_atual = $option.data("km_atual") || 0;
                var indenizacao_carro = $option.data("indenizacao_carro") || 0;
                var indenizacao_terceiros = $option.data("indenizacao_terceiros") || 0;
                console.log("veiculo: tarifa_id ", tarifa_id, " km_atual ", km_atual);
                console.log("veiculo: indenizacao_carro ", indenizacao_carro, " indenizacao_terceiros ", indenizacao_terceiros);
                $("[name=tarifa_id]").val(tarifa_id).trigger("change");
                $("[name=km_saida]").val(km_atual);
                $("[name=indenizacao_carro]").val(indenizacao_carro);
                $("[name=indenizacao_terceiros]").val(indenizacao_terceiros);
                calcularTotal();
            });

            $("[name=tarifa_id]").change(function() {
                var $option   = $(this).find("option:selected");
                var valor     = $option.data("valor") || 0;
                console.log("tarifa: valor ", valor);
                $("[name=diaria]").val(valor);
                calcularTotal();
            });
        });
        ');
    }

    protected function configurarValidacao() {
        $forma_boleto_id = $this->f3->get('settings.softsat.locacao.boleto.forma_pagamento_id');
        $db = $this->f3->get('db');

        Validator::instance()->addRule(
            'boleto_nao_estrangeiro',
            function($field, $value, array $params, array $fields) use($forma_boleto_id, $db) {
                $boleto = $fields['forma_pagamento_id'] == $forma_boleto_id;
                $cliente = $db->exec('SELECT estrangeiro FROM softsat_locacao_cliente WHERE id = ?', $fields['cliente_id'])[0];

                return !$boleto || !$cliente['estrangeiro'];
            },
            'indisponível para estrangeiros'
        );
    }
}
