{% extends 'MDS/VenuesBundle/base-reservations.html.twig' %}{% block pagetitleinterno %} <div class="page-title" style="margin-left:280px"> <h4 class="text-mint_cream"><i class="icon-list position-left text-mint_cream"></i> <span class="text-semibold text-mint_cream">{% trans %}Venues{% endtrans %}</span> - {% trans %}Reservation{% endtrans %}</h4> </div>{% endblock %}{% block breadcrumbs %} <ul class="breadcrumb"> <li><a href="/venues/list"><i class="icon-home2 position-left text-mint_cream"></i>{% trans %}Home{% endtrans %}</a></li> <li class="active"><i class="icon-plus-circle2 position-left text-mint_cream"></i>{% trans %}Edit Reservations{% endtrans %}</li> </ul>{% endblock %}{% block contentReservation %}<div class="row settings-page" id="client-client-subpage"> <div class="panel panel-default"> {# === HEADER: título + acciones === #} <div class="panel-heading clearfix"> <h5 class="panel-title pull-left" style="padding-top:7px;"> <i class="icon-pencil text-vivid_sky_blue"></i> {% trans %}Editar Expediente{% endtrans %} </h5> <div class="pull-right btn-group" role="toolbar"> {# WEB Cotización #} <div class="btn-group"> <button class="btn bg-btn-lavender_gray dropdown-toggle btn-gl" type="button" id="dropdownMenuCotizacion" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> {% trans %}WEB Cotización{% endtrans %} <span class="caret"></span> </button> <ul class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuCotizacion" role="menu" style="left: 0; right: auto;"> <li> <a href="{{ urlCotizacion }}" target="_blank"> {% trans %}Ver web{% endtrans %} </a> </li> <li> <a href="#" onclick="copyProposalLink('{{ urlCotizacion }}'); return false;"> {% trans %}Copiar URL{% endtrans %} </a> </li> {# NUEVA COTIZACION WEB #} <li> <a href="{{ urlCotizacionNew }}" target="_blank"> {% trans %}NUEVO: Ver web{% endtrans %} </a> </li> <li> <a href="#" onclick="copyProposalLink('{{ urlCotizacionNew }}'); return false;"> {% trans %}NUEVO: Copiar URL{% endtrans %} </a> </li> <li> <a href="#" data-mailcontent="{{ msgMailToClient|escape('html_attr') }}" onclick="copyEmail(this.getAttribute('data-mailcontent')); return false;"> {% trans %}NUEVO: Copiar Email para el Cliente{% endtrans %} </a> </li> {# OBSERVACIONES WEB #} <li class="divider" role="separator"></li> <li> <a href="#" data-toggle="modal" data-target="#modalWebObservations"> <i class="fa fa-comments-o" aria-hidden="true"></i> {% trans %}Ver observaciones web{% endtrans %} </a> </li> </ul> </div> {% if aveFile is defined and aveFile is not empty %} <a href="/avexpress/fileedit/{{ aveFile.id }}" target="_blank" class="btn bg-btn-green_av btn-gl text-white -align-left">{% trans %}Expediente AV{% endtrans %}</a> {% endif %} {% if htFile is defined and htFile is not empty %} <a href="/higotrigo/ht/file/{{ htFile.id }}/edit" target="_blank" class="btn bg-btn-orange_cat btn-gl">{% trans %}Expediente Catering{% endtrans %}</a> {% endif %} {% if viewContract %} {% set contactMissing = (reserva.clientContact is empty) and (reserva.contactUnregistered is empty or reserva.nameContactUnregistered is empty) %} {% if contactMissing %} <div class="btn-group" style="display: inline-block; cursor: not-allowed;" data-toggle="tooltip" data-placement="bottom" title="{% trans %}No se pueden gestionar contratos porque el cliente no tiene un contacto asociado ni se han especificado los datos de contacto no registrado (Email y Nombre) en la reserva.{% endtrans %}"> <button class="btn bg-btn-lavender_gray dropdown-toggle btn-gl disabled" type="button" style="pointer-events: none;" disabled="disabled"> {% trans %}Contratos{% endtrans %} <span class="caret"></span> </button> </div> {% else %} <div class="btn-group"> <button class="btn bg-btn-lavender_gray dropdown-toggle btn-gl" type="button" id="dropdownMenuContrato" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> {% trans %}Contratos{% endtrans %} <span class="caret"></span> </button> <ul class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuContrato" role="menu" style="min-width: 250px;"> {% for contract in reservationContracts %} <li class="dropdown-header" style="font-weight: bold; color: #333; background: #f9f9f9; padding: 10px;"> {{ contract.model.title|default('Contrato ' ~ loop.index) }} {% if contract.isSigned %} <span class="badge pull-right" style="background-color: #27ae60; color: #fff; font-size: 10px; margin-top: 1px;"> <i class="icon-checkmark3" style="font-size: 9px;"></i> {% trans %}Firmado{% endtrans %} </span> {% endif %} </li> <li> <a href="/venues/contract/{{ contract.id }}" target="_blank"> <i class="icon-pencil"></i> {% trans %}Versión Editable{% endtrans %} </a> </li> {% if not loop.last %}<li class="divider"></li>{% endif %} {% endfor %} <li class="divider" style="margin: 4px 0;"></li> <li> <a href="#" id="btn-open-signed-contracts" style="color: #101230; font-weight: 600; padding: 8px 15px; background: #f8fafc;"> <i class="icon-file-check position-left" style="color: #27ae60;"></i> {% trans %}Contratos Firmados del Expediente{% endtrans %} </a> </li> </ul> </div> {% endif %} {% endif %} {# Acciones principales #} {% if clientId != 0 %} <a href="/venues/payment/{{ id }}" class="btn bg-btn-limerick btn-gl"> {% trans %}Pagos y Proformas de Depósito{% endtrans %} <i class="icon-coin-euro position-right"></i> </a> <a href="/venues/selinvoice/{{ id }}" class="btn bg-btn-vivid_sky_blue btn-gl"> {% trans %}Facturación{% endtrans %} <i class="icon-eye8 position-right"></i> </a> {% endif %} {% if is_granted('ROLE_ADMIN') %} <a href="/venues/summary/prices/{{ id }}" class="btn bg-btn-rich_black btn-gl"> {% trans %}Resumen Económico{% endtrans %} <i class="icon-balance position-right"></i> </a> {% endif %} <a href="#" class="btn bg-btn-vivid_sky_blue btn-gl" data-toggle="modal" data-target="#tracingsModal" style="color: white;"> <i class="icon-history position-left"></i> Seguimientos <span class="badge" style="background-color: rgba(0,0,0,0.2); color: white;">{{ tracings|length }}</span> </a> <a href="/venues/delete/{{ id }}" class="btn bg-btn-trash btn-gl" onclick="return confirm('¿Deseas CANCELAR esta reserva por completo?');"> {% trans %}Cancelar Reserva{% endtrans %} <i class="icon-cancel-circle2 position-right"></i> </a> </div> </div> {# === BODY === #} <div class="panel-body"> <div class="row settings-page"> {# flashbags #} {% for flashMessage in app.session.flashbag.get('mensajereservation') %} <div class="hidden alertFlashMensaje" data-mensaje="{{ flashMessage|raw }}"></div> {% endfor %} {% for flashMessage in app.session.flashbag.get('mensajereservationerror') %} <div class="hidden alertFlashMensajeError" data-mensajeerror="{{ flashMessage|raw }}"></div> {% endfor %} {% for flashMessage in app.session.flashbag.get('mensaje') %} <div class="hidden alertFlashMensaje" data-mensaje="{{ flashMessage|raw }}"></div> {% endfor %} {% for flashMessage in app.session.flashbag.get('mensajeerror') %} <div class="hidden alertFlashMensajeError" data-mensajeerror="{{ flashMessage|raw }}"></div> {% endfor %} <div class="col-xs-12"> <div class="margen-15"></div> {# FORMULARIO PRINCIPAL DE EDICIÓN DE RESERVA #} <div class="panel panel-default"> <div class="panel-body"> <style> .stepper { display: flex; justify-content: space-between; align-items: center; padding: 20px; border-radius: 10px; color: white; margin-bottom: 30px; } .step { text-align: center; position: relative; flex: 1; } .step:not(:last-child)::after { content: ""; position: absolute; top: 24px; right: -50%; height: 4px; width: 100%; background: #d3d3d3; z-index: 0; transition: background-color 0.5s ease; } .step.completed:not(:last-child)::after { background: #32aaf0; } .step .icon { background: #fff; border-radius: 50%; padding: 15px; font-size: 24px; z-index: 1; position: relative; display: inline-block; font-family: 'icomoon'; color: #101230; transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275); cursor: pointer; box-shadow: 0 2px 5px rgba(0,0,0,0.1); } .step.completed .icon, .step.active .icon { background: #32aaf0; color: #fafffd; } .step.active .icon { transform: scale(1.15); box-shadow: 0 0 15px rgba(50, 170, 240, 0.4); } .step span { display: block; margin-top: 8px; font-weight: bold; font-size: 14px; color: #d3d3d3; transition: color 0.4s ease, transform 0.4s ease; } .step.completed span { color: #101230; } .step.active span { color: #32aaf0; transform: translateY(2px); } </style> {% set pasos = ['Iniciado', 'Cotizado', 'Bloqueo', 'Confirmed', 'Invoiced'] %} {% set iconos = { 'Iniciado': 'icon-play', 'Cotizado': 'icon-coin-euro', 'Bloqueo': 'icon-lock', 'Confirmed': 'icon-checkmark-circle', 'Invoiced': 'icon-file-text' } %} {% set estadoActual = reserva.status %} {% set estadoIndex = -1 %} {% for i in 0..pasos|length - 1 %} {% if pasos[i] == reserva.status %} {% set estadoIndex = i %} {% endif %} {% endfor %} <div class="stepper" id="estado-stepper" data-estado-index="{{ estadoIndex }}"> {% for paso in pasos %} {% set index = loop.index0 %} {% set clase = '' %} {% if index < estadoIndex %} {% set clase = 'completed' %} {% elseif index == estadoIndex %} {% set clase = 'active' %} {% endif %} {% set claseDeshabilitado = (paso == 'Iniciado') ? 'disabled' : '' %} <div class="step {{ claseDeshabilitado }}" data-step-index="{{ index }}" data-step-type="{{ clase }}"> <div class="icon {{ iconos[paso] }}"></div> <span>{{ paso|upper }}</span> </div> {% endfor %} </div> {% trans_default_domain 'messages' %} {{ form_start(form, { 'action': path('reservations_update', {'id': id}), 'attr': { 'class': 'form-horizontal', 'role': 'form', 'autocomplete': 'off' } }) }} <div class="form-group"> <label class="col-sm-3 control-label">{% trans %}Venues ID{% endtrans %}</label> <div class="col-sm-9"> <b><p class="form-control-static"> #{{ id }} —> {% trans %}Created by Agent{% endtrans %}: {{ createdBy }} ({{ reserva.createdAt|date('d/m/Y') }}) </p></b> </div> </div> <div class="form-group"> {{ form_label(form.title, null, {'label_attr': {'class': 'col-sm-3 control-label'}}) }} <div class="col-sm-6"> {{ form_widget(form.title, {'attr': {'class': 'form-control'}}) }} {{ form_errors(form.title) }} </div> <div class="col-sm-3"> <div class="checkbox" style="margin:0"> <label> {{ form_widget(form.sucoe, {'attr': {'class': 'switchery-info'}}) }} {{ form_label(form.sucoe) }} </label> </div> </div> </div> <div class="form-group"> {{ form_label(form.client, null, {'label_attr': {'class': 'col-sm-3 control-label'}}) }} <div class="col-sm-5"> {{ form_widget(form.client, {'attr': {'class': 'form-control select2'}}) }} {{ form_errors(form.client) }} </div> <div class="col-sm-1"> <a href="/client/add" class="btn bg-btn-vivid_sky_blue btn-gl" target="_blank"> {% trans %}Add Client{% endtrans %} <i class="icon-user-plus position-right"></i> </a> </div> </div> <div class="form-group"> <label for="client_contact" class="col-sm-3 control-label">{% trans %}Contacto{% endtrans %}</label> <div class="col-sm-9"> <div class="InputClientContactSpinner"> {{ form_widget(form.clientContact) }} <select class="form-control select2" id="ui_client_contact_selector" onchange="document.getElementById('{{ form.clientContact.vars.id }}').value = this.value;"> <option value="" selected="selected">{% trans %}Seleccione un contacto{% endtrans %}</option> {% for contact in clientsContact %} <option value="{{ contact.id }}" {% if contact.id == form.clientContact.vars.value %}selected{% endif %}> {{ contact.name }} {{ contact.lastName }} ({{ contact.email }}) </option> {% endfor %} </select> </div> <span class="help-block">{{ form_errors(form.clientContact) }}</span> </div> </div> <div class="form-group"> <label class="col-sm-3 control-label">{% trans %}Contacto No Registrado{% endtrans %}</label> <div class="col-sm-9"> <div class="row"> <div class="col-sm-4"> {{ form_widget(form.contactUnregistered, {'attr': {'class': 'form-control', 'placeholder': 'Correo electrónico'}}) }} {{ form_errors(form.contactUnregistered) }} </div> <div class="col-sm-4"> {{ form_widget(form.nameContactUnregistered, {'attr': {'class': 'form-control', 'placeholder': 'Nombre y apellido'}}) }} {{ form_errors(form.nameContactUnregistered) }} </div> <div class="col-sm-4"> {{ form_widget(form.phoneContactUnregistered, {'attr': {'class': 'form-control', 'placeholder': 'Teléfono'}}) }} {{ form_errors(form.nameContactUnregistered) }} </div> </div> </div> </div> <div class="form-group"> {{ form_label(form.status, null, {'label_attr': {'class': 'col-sm-3 control-label'}}) }} <div class="col-sm-3"> {{ form_widget(form.status, {'attr': {'class': 'form-control select2'}}) }} {{ form_errors(form.status) }} </div> </div> <div class="form-group"> {{ form_label( form.dateStart, null, {'label_attr': {'class': 'col-sm-3 control-label'}} ) }} <div class="col-sm-2"> {{ form_widget(form.dateStart, { 'attr': { 'class': 'form-control', 'placeholder': 'Fecha de Inicio' }, 'disabled': true }) }} {{ form_errors(form.dateStart) }} </div> {{ form_label( form.dateEnd, null, {'label_attr': {'class': 'col-sm-2 control-label text-right'}} ) }} <div class="col-sm-2"> {{ form_widget(form.dateEnd, { 'attr': { 'class': 'form-control', 'placeholder': 'Fecha de Fin' }, 'disabled': true }) }} {{ form_errors(form.dateEnd) }} </div> <div class="col-sm-3"> <button type="button" class="btn bg-btn-vivid_sky_blue btn-gl" data-toggle="modal" data-target="#modalReschedule"> {% trans %}Reprogramar las fechas del evento{% endtrans %} <i class="icon-calendar position-right"></i> </button> </div> </div> <div class="form-group"> <label class="col-sm-3 control-label"> {{ form_label(form.daysBlock) }} / {{ form_label(form.days) }} </label> <div class="col-sm-3"> {% set daysBlockAttrs = {'class': 'form-control'} %} {% if form.status.vars.value == 'Bloqueo' %} {% set daysBlockAttrs = daysBlockAttrs|merge({'disabled': 'disabled'}) %} {% endif %} {{ form_widget(form.daysBlock, {'attr': daysBlockAttrs}) }} {{ form_errors(form.daysBlock) }} </div> <div class="col-sm-6"> {{ form_widget(form.days, {'attr': {'class': 'form-control', 'id': 'days', 'placeholder': 'Fecha límite bloqueo'}}) }} {{ form_errors(form.days) }} </div> </div> <div class="form-group"> {% if form.status.vars.value == 'Bloqueo' %} {{ form_label(form.dateNextMailAlert, null, {'label_attr': {'class': 'col-sm-3 control-label'}}) }} <div class="col-sm-3"> {{ form_widget(form.dateNextMailAlert, {'attr': {'class': 'form-control'}}) }} </div> {% else %} <div style="display:none;"> {{ form_widget(form.dateNextMailAlert) }} </div> {% endif %} </div> {{ form_widget(form.priority) }} {{ form_widget(form.contract) }} <div class="form-group"> {{ form_label(form.comHtGp, null, {'label_attr': {'class': 'col-sm-3 control-label'}}) }} <div class="col-sm-1"> {{ form_widget(form.comHtGp, { 'attr': { 'class': 'form-control', 'placeholder': '14 (Por defecto)' } }) }} {{ form_errors(form.comHtGp) }} </div> </div> <div class="form-group"> {{ form_label(form.description, null, {'label_attr': {'class': 'col-sm-3 control-label'}}) }} <div class="col-sm-9"> {{ form_widget(form.description) }} {{ form_errors(form.description) }} </div> </div> <div class="col-md-4 margen-20" style="padding: 5px 15px;"></div> <div class="col-md-4 margen-20" style="padding: 5px 15px;"> <div class="form-group form-group-material"> <div class="text-center"> {{ form_widget(form.save, {'attr': {'class': 'btn bg-btn-limerick btn-block'}}) }} </div> </div> </div> <div class="col-md-4 margen-20" style="padding: 5px 15px;"></div> {{ form_end(form) }} </div> </div> {# FORMULARIO: AÑADIR SALA INDIVIDUAL #} <div class="panel panel-default"> <div class="panel-body"> <div class="row"> <div class="col-xs-12 text-center"> <h3><strong>{% trans %}RESERVA DE SALAS{% endtrans %}</strong></h3> </div> <div class="col-xs-12"> <legend class="border text-vivid_sky_blue">{% trans %}Salas, Montaje y Desmontaje (Cargar día a día){% endtrans %}</legend> </div> </div> <form name="mds_venuesbundle_revervation_form2" method="post" action="/venues/createsimplelounge/{{ id }}" class="form-inline" role="form" autocomplete="off"> <div class="row" style="margin-bottom:10px"> <div class="col-sm-2"> <div class="form-group"> <label for="reservation_sala_salasPrecargadas" class="control-label"> {% trans %}Salas Precargadas{% endtrans %} * </label> <select id="reservation_sala_salasPrecargadas" name="reservation_sala[salaPrecargadas]" class="form-control select2" required> <option value="">{% trans %}Seleccione una sala{% endtrans %}</option> {% for loungePre in loungesPre %} <option value="{{ loungePre.id }}">{{ loungePre.name|capitalize }}</option> {% endfor %} </select> </div> </div> <div class="col-sm-2"> <div class="form-group"> <label for="reservation_sala_date" class="control-label">{% trans %}Date{% endtrans %} *</label> <input type="date" id="reservation_sala_date" name="reservation_sala[dateStart]" class="form-control" required> </div> </div> <div class="col-sm-2"> <div class="form-group"> <label for="reservation_sala_type" class="control-label">{% trans %}Type{% endtrans %}</label> <select id="reservation_sala_type" name="reservation_sala[type]" class="form-control" style="padding:0px;text-align-last: center;"> <option value="" selected>Día de Evento</option> <option value="Montaje">Montaje</option> <option value="Desmontaje">Desmontaje</option> </select> </div> </div> <input type="hidden" name="reservation_sala[servicePrice]" id="reservation_sala_price" value="0"> <div class="col-sm-1"> <div class="form-group"> <label for="reservation_sala_hourStart" class="control-label">{% trans %}Inicio{% endtrans %} *</label> <input type="text" class="form-control" name="reservation_sala[hourStart]" id="reservation_sala_hourStart" placeholder="00:00" required> </div> </div> <div class="col-sm-1"> <div class="form-group"> <label for="reservation_sala_hourEnd" class="control-label">{% trans %}Fin{% endtrans %} *</label> <input type="text" class="form-control" name="reservation_sala[hourEnd]" id="reservation_sala_hourEnd" placeholder="00:00" required> </div> </div> <div class="col-sm-1"> <div class="form-group"> <label for="reservation_sala_pax" class="control-label">{% trans %}Pax{% endtrans %}</label> <input type="text" class="form-control" name="reservation_sala[pax]" id="reservation_sala_pax" required> </div> </div> <div class="col-sm-1"> <div class="form-group"> <label for="reservation_sala_servicePrice" class="control-label">{% trans %}Precio{% endtrans %}</label> <input type="number" step="any" class="form-control" name="reservation_sala[servicePrice]" id="reservation_sala_servicePrice" required> </div> </div> <div class="col-sm-1"> <div class="form-group"> <label for="reservation_sala_idQuote" class="control-label">{% trans %}# Opción{% endtrans %}</label> <input type="number" class="form-control" name="reservation_sala[idQuote]" id="reservation_sala_idQuote"> </div> </div> <div class="col-sm-1"> <div class="form-group"> <label class="control-label" style="display:block"> </label> <div class="input-group"> <span class="group-btn"> <button type="submit" id="reservation_sala_save" name="reservation_sala[save]" class="btn bg-btn-limerick"> {% trans %}Add{% endtrans %} </button> </span> </div> </div> </div> </div> </form> </div> </div> {# SECCIÓN COTIZADO Y GRID DE OPCIONES #} {% if numeroItems > 0 %} <div class="panel panel-default"> <div class="panel-body"> <div class="row"> <div class="col-xs-12"> <strong class="text-vivid_sky_blue"> <legend class="border"> <div class="row"> <div class="col-xs-10"> <h3>{% trans %}COTIZADO{% endtrans %}</h3> </div> <div class="col-xs-2"> {% set firstLevel = arrayLoungesInFile|first %} {% set firstItem = firstLevel|first %} <label for="reservation_idWebLanguage" class="control-label">{% trans %}Idioma web{% endtrans %}</label> <select id="reservation_idWebLanguage" class="form-control" onchange="changeLanguageWeb(this.value)"> {% for language, value in languagesWeb %} <option value="{{ value }}" {% if firstItem.language is null or firstItem.language == value %}selected{% endif %}> {{ language }} </option> {% endfor %} </select> </div> </div> </legend> </strong> </div> </div> <form name="mds_venuesbundle_loungrid" method="post" action="/venues/updateloungegrid" class="form-horizontal" role="form" autocomplete="off"> <input type="hidden" name="reservationId" value="{{ id }}"> <input type="hidden" name="reservation_global_lounge[language]" id="reservation_global_lounge_language_hidden" value="{{ firstItem.language }}"> {% for keyRank, itemRankQuote in arrayLoungesByDay %} <!-- CARD MINIMALISTA DE LA OPCIÓN --> <div class="develup-card" style="background: #ffffff; border: 1px solid #ded9e2; border-radius: 8px !important; padding: 30px; margin-bottom: 45px; box-shadow: 0 4px 12px rgba(16, 18, 48, 0.04);"> <!-- Cabecera interna de la Opción --> <div class="row" style="margin-bottom: 25px; padding-bottom: 15px; border-bottom: 1px solid #ded9e2;"> <div class="col-sm-6"> <h3 class="text-limerick" style="font-size: 22px; font-weight: 700; margin: 0; letter-spacing: -0.5px;"> {% trans %}Opción{% endtrans %} <span class="text-limerick" style="font-weight: 700;"># {{ keyRank }}</span> </h3> </div> <div class="col-sm-6 text-right"> <a class="btn bg-btn-limerick btn-sm" href="/venues/checkquote/{{ id }}/{{ keyRank }}" onclick="return confirm('{% trans %}¿Deseas eliminar todas las otras cotizaciones?{% endtrans %}');" style="border-radius: 8px !important; font-weight: bold;"> <i class="icon-check"></i> {% trans %}Aprobar{% endtrans %} </a> <a class="btn bg-btn-trash btn-sm" href="/venues/deletequote/{{ id }}/{{ keyRank }}" onclick="return confirm('{% trans %}¿Deseas eliminar la cotización?{% endtrans %}');" style="border-radius: 8px !important; margin-left: 5px;"> <i class="icon-trash"></i> </a> </div> </div> <!-- Contenido de la Opción --> <div style="padding: 0 5px;"> {% for key, itemDay in itemRankQuote %} <!-- Encabezado de Día --> <div class="row" style="margin-top: 25px; margin-bottom: 15px;"> <div class="col-sm-6"> <h4 class="text-vivid_sky_blue" style="margin: 0; font-weight: 600; font-size: 15px; display: inline-flex; align-items: center; gap: 6px;"> <i class="icon-calendar"></i> {{ key|slice(6,2) }}/{{ key|slice(4,2) }}/{{ key|slice(0,4) }} </h4> </div> <div class="col-sm-6 text-right"> <a href="/venues/duplicateday/{{ id }}/{{ key|slice(6,2) }}-{{ key|slice(4,2) }}-{{ key|slice(0,4) }}/{{ keyRank }}" class="btn bg-btn-vivid_sky_blue btn-xs" style="border-radius: 8px !important; font-weight: bold; padding: 4px 10px;"> <i class="icon-docs"></i> {% trans %}Duplicar Día{% endtrans %} </a> </div> </div> <!-- Tabla de Edición de Salas --> <div class="table-responsive" style="margin-bottom: 20px;"> <table class="table" style="margin-bottom: 0;"> <thead> <tr class="text-rich_black" style="border-bottom: 1px solid #ded9e2; font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px;"> <th style="width: 15%; padding-bottom: 8px;">{% trans %}Fecha{% endtrans %}</th> <th style="width: 25%; padding-bottom: 8px;">{% trans %}Sala{% endtrans %}</th> <th style="width: 12%; padding-bottom: 8px;">{% trans %}Precio{% endtrans %}</th> <th style="width: 18%; padding-bottom: 8px;">{% trans %}IVA{% endtrans %}</th> <th style="width: 12%; text-align: center; padding-bottom: 8px;"> {% set hasMontaje = false %} {% for item in itemDay %} {% if item.type is not null %} {% set hasMontaje = true %} {% endif %} {% endfor %} {% if hasMontaje %}{% trans %}Tipo{% endtrans %}{% else %}{% trans %}Personas{% endtrans %}{% endif %} </th> <th style="width: 8%; text-align: center; padding-bottom: 8px;">{% trans %}Inicio{% endtrans %}</th> <th style="width: 8%; text-align: center; padding-bottom: 8px;">{% trans %}Fin{% endtrans %}</th> <th style="width: 2%; padding-bottom: 8px;"></th> </tr> </thead> <tbody> {% for item in itemDay %} {% set ymd = key|slice(0,4) ~ key|slice(4,2) ~ key|slice(6,2) %} <tr style="border-bottom: 1px dotted #ded9e2;"> <td style="vertical-align: middle; border: none; padding: 8px 4px;"> <input type="date" class="form-control input-sm text-rich_black" name="lounge[{{ item.id }}][{{ ymd }}][{{ item.loungeName }}][newDate]" id="newDate_{{ item.id }}" value="{{ key|slice(0,4) }}-{{ key|slice(4,2) }}-{{ key|slice(6,2) }}" style="border-radius: 8px !important;"> </td> <td style="vertical-align: middle; border: none; padding: 8px 4px;"> <input type="text" class="form-control input-sm text-rich_black" id="loungeName_{{ item.id }}" value="{{ item.loungeName }}" disabled style="font-weight: bold; background: transparent; border: none; box-shadow: none;"> <input type="hidden" name="lounge[{{ item.id }}][{{ ymd }}][{{ item.loungeName }}][name]" value="{{ item.loungeName }}"> </td> <td style="vertical-align: middle; border: none; padding: 8px 4px;"> <div class="input-group input-group-sm"> <input type="number" step="any" class="form-control text-rich_black" name="lounge[{{ item.id }}][{{ ymd }}][{{ item.loungeName }}][price]" id="price_{{ item.id }}" value="{{ item.servicePrice }}" style="border-radius: 8px 0 0 8px !important;"> <span class="input-group-addon text-rich_black" style="background: transparent; border-color: #ccc; font-weight: bold; border-radius: 0 8px 8px 0 !important;">€</span> </div> </td> <td style="vertical-align: middle; border: none; padding: 8px 4px;"> <select class="form-control input-sm text-rich_black" id="iva_{{ item.id }}" {% if true %}disabled{% endif %} style="background: #fafafa; border-radius: 8px !important;"> <option value="">{% trans %}Selecciona un IVA{% endtrans %}</option> {% for vat in sageVatRates %} <option value="{{ vat.id }}" {% if vat.id == item.sageIva.id %}selected{% endif %}> {{ vat.name }} ({{ vat.iva|number_format(2, '.', '') }}%) </option> {% endfor %} </select> <input type="hidden" name="lounge[{{ item.id }}][{{ ymd }}][{{ item.loungeName }}][iva]" value="{{ item.sageIva.id }}"> </td> <td style="vertical-align: middle; border: none; padding: 8px 4px;"> {% if item.type is null %} <input type="number" step="1" class="form-control input-sm text-center text-rich_black" name="lounge[{{ item.id }}][{{ ymd }}][{{ item.loungeName }}][pax]" id="pax_{{ item.id }}" value="{{ item.pax }}" style="border-radius: 8px !important;"> {% else %} <input type="text" class="form-control input-sm text-center text-rich_black" name="lounge[{{ item.id }}][{{ ymd }}][{{ item.loungeName }}][type]" id="type_{{ item.id }}" value="{{ item.type }}" readonly style="background: transparent; border: none; box-shadow: none; font-weight: bold;"> {% endif %} </td> <td style="vertical-align: middle; border: none; padding: 8px 4px;"> <input type="text" class="form-control input-sm text-center text-rich_black" name="lounge[{{ item.id }}][{{ ymd }}][{{ item.loungeName }}][dateHourMinStart]" id="start_{{ item.id }}" value="{{ item.dateStart|date('H:i') }}" style="border-radius: 8px !important;"> </td> <td style="vertical-align: middle; border: none; padding: 8px 4px;"> <input type="text" class="form-control input-sm text-center text-rich_black" name="lounge[{{ item.id }}][{{ ymd }}][{{ item.loungeName }}][dateHourMinEnd]" id="end_{{ item.id }}" value="{{ item.dateEnd|date('H:i') }}" style="border-radius: 8px !important;"> </td> <td class="text-center" style="vertical-align: middle; border: none; padding: 8px 4px;"> {% if item.id != 0 %} <a class="bg-btn-trash" onclick="return confirm('¿Deseas eliminar este elemento?');" href="/venues/deleteitemsimple/{{ item.id }}/{{ key|slice(6,2) }}-{{ key|slice(4,2) }}-{{ key|slice(0,4) }}" title="{% trans %}Eliminar este elemento{% endtrans %}" style="font-size: 15px; border-radius: 8px;"><i class="icon-trash"></i></a> {% else %} <a class="text-muted" href="/venues/edit/{{ id }}" title="{% trans %}Antes debe guardar el expediente{% endtrans %}" style="font-size: 15px;"><i class="icon-lock"></i></a> {% endif %} </td> </tr> {% endfor %} </tbody> </table> </div> {% endfor %} <!-- SERVICIOS Y EXTRAS ASOCIADOS A ESTA OPCIÓN --> <div style="margin-top: 30px; padding: 15px; background-color: #fcfcfc; border: 1px solid #e9e9e9; border-radius: 8px;"> <h5 class="text-vivid_sky_blue" style="margin-top: 0; font-weight: bold; font-size: 14px;"> <i class="icon-box position-left"></i> {% trans %}Servicios Contratados para la Opción{% endtrans %} #{{ keyRank }} </h5> {% if servicesByRank[keyRank] is defined and servicesByRank[keyRank] is not empty %} <div class="table-responsive"> <table class="table table-condensed table-hover" style="margin-bottom: 0;"> <thead> <tr class="active text-muted" style="font-size: 11px;"> <th>{% trans %}Categoría{% endtrans %}</th> <th>{% trans %}Servicio / Producto{% endtrans %}</th> <th class="text-center">{% trans %}Fecha{% endtrans %}</th> <th class="text-center">{% trans %}Uds{% endtrans %}</th> <th class="text-right">{% trans %}Precio Un.{% endtrans %}</th> <th class="text-right">{% trans %}Importe Neto{% endtrans %}</th> </tr> </thead> <tbody> {% for rankService in servicesByRank[keyRank] %} {% set priceNet = rankService.price * rankService.units %} <tr> <td> <span class="label label-info" style="border-radius: 4px;"> {{ rankService.serviceCatName|default('Audiovisuales') }} </span> </td> <td><strong>{{ rankService.name }}</strong></td> <td class="text-center">{{ rankService.dateInAt ? rankService.dateInAt|date('d/m/Y') : '-' }}</td> <td class="text-center">{{ rankService.units }}</td> <td class="text-right">{{ rankService.price|number_format(2, ',', '.') }} €</td> <td class="text-right"><strong>{{ priceNet|number_format(2, ',', '.') }} €</strong></td> </tr> {% endfor %} </tbody> </table> </div> {% else %} <p class="text-muted text-center" style="margin: 10px 0 0 0; font-size: 12px; font-style: italic;"> {% trans %}No hay servicios ni paquetes extras asociados específicamente a la Opción{% endtrans %} #{{ keyRank }}. </p> {% endif %} </div> {# ====== Bloque de textos por lounge/opción ====== #} {% if arrayLoungesInFile[keyRank] is defined and arrayLoungesInFile[keyRank] is not empty %} {% for item in arrayLoungesInFile[keyRank] %} <div style="margin: 25px 0 15px 0; padding: 12px 0; border-top: 1px solid #ded9e2; border-bottom: 1px solid #ded9e2;"> <div class="row" style="display: flex; align-items: center; flex-wrap: wrap;"> <div class="col-sm-4"> <span class="text-rich_black" style="font-size: 13px; font-weight: bold; letter-spacing: 0.2px;"> <i class="icon-settings text-vivid_sky_blue" style="margin-right: 5px;"></i> {% trans %}Audiovisuales{% endtrans %} </span> </div> <div class="col-sm-8 text-right-sm"> <label class="checkbox-inline text-rich_black" style="font-weight: 600; font-size: 12px; margin-top: 0; user-select: none; margin-right: 20px;"> <input type="hidden" name="reservation_global_lounge[{{ item.idLounge }}][showAudiovisualPrice]" value="0"> <input type="checkbox" name="reservation_global_lounge[{{ item.idLounge }}][showAudiovisualPrice]" id="show_av_price_{{ item.idLounge }}" value="1" {% if item.showAudiovisualPrice == true or item.showAudiovisualPrice == 1 %}checked="checked"{% endif %}> {% trans %}Mostrar y sumar precio del paquete AV{% endtrans %} </label> <label class="checkbox-inline text-rich_black" style="font-weight: 600; font-size: 12px; margin-top: 0; user-select: none;"> <input type="hidden" name="reservation_global_lounge[{{ item.idLounge }}][showAudiovisualPackage]" value="0"> <input type="checkbox" name="reservation_global_lounge[{{ item.idLounge }}][showAudiovisualPackage]" id="show_av_package_{{ item.idLounge }}" value="1" {% if item.showAudiovisualPackage == true or item.showAudiovisualPackage == 1 %}checked="checked"{% endif %}> {% trans %}Mostrar paquetes AV{% endtrans %} </label> </div> </div> </div> <div class="row" style="margin-top: 20px;"> <div class="col-xs-12"> <ul class="nav nav-tabs nav-tabs-solid" role="tablist" style="margin-bottom: 0;"> <li class="active" role="presentation"> <a href="#resumenDescriptivo-{{item.idLounge}}-{{keyRank}}" aria-controls="resumenDescriptivo-{{item.idLounge}}-{{keyRank}}" role="tab" data-toggle="tab" style="font-weight: bold; border-radius: 8px 8px 0 0 !important;"><i class="icon-notebook"></i> {% trans %}Resumen Descriptivo{% endtrans %}</a> </li> <li role="presentation"> <a href="#general-{{item.idLounge}}-{{keyRank}}" aria-controls="general-{{item.idLounge}}-{{keyRank}}" role="tab" data-toggle="tab" style="font-weight: bold; border-radius: 8px 8px 0 0 !important;"><i class="icon-info"></i> {% trans %}Importante (Texto General){% endtrans %}</a> </li> <li role="presentation"> <a href="#horarios-{{item.idLounge}}-{{keyRank}}" aria-controls="horarios-{{item.idLounge}}-{{keyRank}}" role="tab" data-toggle="tab" style="font-weight: bold; border-radius: 8px 8px 0 0 !important;"><i class="icon-clock"></i> {% trans %}Importante (Horarios){% endtrans %}</a> </li> <li role="presentation"> <a href="#parking-{{item.idLounge}}-{{keyRank}}" aria-controls="parking-{{item.idLounge}}-{{keyRank}}" role="tab" data-toggle="tab" style="font-weight: bold; border-radius: 8px 8px 0 0 !important;"><i class="icon-direction"></i> {% trans %}Importante (Parking){% endtrans %}</a> </li> </ul> <div class="tab-content" style="background: transparent; padding: 20px 0 0 0; border: none;"> <div role="tabpanel" class="tab-pane active" id="resumenDescriptivo-{{item.idLounge}}-{{keyRank}}"> <textarea name="reservation_global_lounge[{{ item.idLounge }}][importantDescription]" class="form-control summernote-small resumenDescriptivo-{{ item.idLounge }}-editor" rows="3">{{ item.loungeImportantDescription }}</textarea> </div> <div role="tabpanel" class="tab-pane" id="general-{{item.idLounge}}-{{keyRank}}"> <textarea name="reservation_global_lounge[{{ item.idLounge }}][importantDescGeneralText]" class="form-control summernote-small general-{{ item.idLounge }}-editor">{{ item.loungeImportantDescGeneralText }}</textarea> </div> <div role="tabpanel" class="tab-pane" id="horarios-{{item.idLounge}}-{{keyRank}}"> <textarea name="reservation_global_lounge[{{ item.idLounge }}][importantDescSchedules]" class="form-control summernote-small horarios-{{ item.idLounge }}-editor">{{ item.loungeImportantDescSchedules }}</textarea> </div> <div role="tabpanel" class="tab-pane" id="parking-{{item.idLounge}}-{{keyRank}}"> <textarea name="reservation_global_lounge[{{ item.idLounge }}][importantDescParking]" class="form-control summernote-small parking-{{ item.idLounge }}-editor">{{ item.loungeImportantDescParking }}</textarea> </div> </div> </div> </div> {% endfor %} {% endif %} </div> </div> {% endfor %} <div class="row" style="margin-top: 40px; margin-bottom: 50px;"> <div class="col-md-4 col-md-offset-4 text-center"> <button type="submit" name="mds_venuesbundle_reservation[save]" class="btn bg-btn-limerick btn-block" style="font-weight: bold; font-size: 15px; border-radius: 8px !important; padding: 12px; text-transform: uppercase; letter-spacing: 1px;"> <i class="icon-disc"></i> {% trans %}Guardar Cotizaciones{% endtrans %} </button> </div> </div> </form> {# ========================================================== FORMULARIO DUPLICAR COTIZACIÓN ========================================================== #} <form name="mds_greenpatiobundle_addquote" method="post" action="{{ path('reservations_duplicate_quote') }}" class="duplicate-quote-form" role="form" autocomplete="off"> {# ID DE LA RESERVA #} <input type="hidden" name="addquote[reservationId]" value="{{ id }}"> {# ====================================================== CONTENEDOR PRINCIPAL ====================================================== #} <div class="duplicate-quote-container"> {# ================================================== OPCIÓN ORIGEN ================================================== #} <div class="duplicate-source-wrapper"> <div class="duplicate-section-title"> <i class="icon-copy"></i> <div> <div class="duplicate-section-title-main"> Opción a duplicar </div> <div class="duplicate-section-title-description"> Indica el número de opción que quieres utilizar como origen. </div> </div> </div> <div class="duplicate-source-field"> <label for="addquote_idQuote"> Número de opción </label> <input type="number" class="form-control" name="addquote[idQuote]" id="addquote_idQuote" placeholder="# Opción" title="Número de opción que deseas duplicar"> </div> </div> {# ================================================== SALAS DESTINO ================================================== #} <div class="duplicate-quote-wrapper"> <div class="duplicate-section-title"> <i class="icon-office"></i> <div> <div class="duplicate-section-title-main"> Salas destino </div> <div class="duplicate-section-title-description"> Selecciona una o varias salas y establece su precio. </div> </div> </div> {# ================================================== ESPACIOS ================================================== #} <div class="duplicate-spaces"> {% for spaceGroup in loungesBySpace %} {% set spaceId = 'duplicate-space-' ~ loop.index %} {# ================================================== TARJETA DEL ESPACIO ================================================== #} <div class="duplicate-space-card"> {# CABECERA DEL ESPACIO #} <button type="button" class="duplicate-space-header" data-toggle="collapse" data-target="#{{ spaceId }}" aria-expanded="false" aria-controls="{{ spaceId }}" > <span class="duplicate-space-title"> <i class="icon-office"></i> <strong> {{ spaceGroup.name }} </strong> <span class="duplicate-space-count"> {{ spaceGroup.lounges|length }} {% if spaceGroup.lounges|length == 1 %} sala {% else %} salas {% endif %} </span> </span> <i class="icon-chevron-down duplicate-space-chevron"></i> </button> {# ================================================== CONTENIDO DEL ESPACIO ================================================== #} <div id="{{ spaceId }}" class="collapse" > <div class="duplicate-space-body"> {# ================================================== CABECERA DE LAS SALAS ================================================== #} <div class="duplicate-lounge-header"> <div class="duplicate-col-select"> Seleccionar </div> <div class="duplicate-col-name"> Sala </div> <div class="duplicate-col-price"> Precio </div> </div> {# ================================================== LISTADO DE SALAS ================================================== #} {% for loungePre in spaceGroup.lounges %} <div class="duplicate-lounge-row"> {# CHECKBOX #} <div class="duplicate-col-select"> <label class="duplicate-checkbox-wrapper"> <input type="checkbox" class="duplicate-lounge-check" id="duplicate_lounge_{{ loungePre.id }}" name="addquote[salas][{{ loungePre.id }}][selected]" value="1" > </label> </div> {# NOMBRE DE LA SALA #} <div class="duplicate-col-name"> <label for="duplicate_lounge_{{ loungePre.id }}" class="duplicate-lounge-name" > {{ loungePre.name }} </label> </div> {# PRECIO #} <div class="duplicate-col-price"> <div class="input-group duplicate-price-group"> <input type="number" step="0.01" min="0" class="form-control duplicate-lounge-price" name="addquote[salas][{{ loungePre.id }}][price]" placeholder="Precio" disabled > <span class="input-group-addon"> € </span> </div> </div> </div> {% endfor %} </div> </div> </div> {% endfor %} </div> </div> {# ================================================== ELIMINAR OPCIÓN ORIGEN ================================================== #} <div class="duplicate-delete-wrapper"> <div class="alert alert-warning"> <label style="margin: 0; cursor: pointer;"> <input type="checkbox" name="addquote[deleteSource]" value="1" > <strong> Eliminar la opción origen después de duplicarla </strong> </label> <br> <small> La opción original solo se eliminará si todas las nuevas opciones se crean correctamente. </small> </div> </div> {# ================================================== BOTÓN DUPLICAR ================================================== #} <div class="duplicate-submit-wrapper"> <button type="submit" id="mds_greenpatiobundle_reservation_addquote" name="mds_greenpatiobundle_reservation[save]" class="btn bg-btn-vivid_sky_blue" > Duplicar opciones </button> </div> </div> </form> {# ========================================================== CSS ========================================================== #} <style> /* ========================================================== FORMULARIO PRINCIPAL ========================================================== */ .duplicate-quote-form { width: 100%; margin: 0; padding: 0; } /* ========================================================== CONTENEDOR CENTRAL ========================================================== */ .duplicate-quote-container { width: 100%; max-width: 1050px; margin: 0 auto; padding: 30px 20px 40px 20px; box-sizing: border-box; } /* ========================================================== TÍTULOS DE SECCIÓN ========================================================== */ .duplicate-section-title { display: flex; align-items: flex-start; width: 100%; margin-bottom: 18px; color: #101230; } .duplicate-section-title > i { flex-shrink: 0; margin-right: 10px; margin-top: 2px; color: #32aaf0; font-size: 18px; } .duplicate-section-title-main { color: #101230; font-size: 16px; font-weight: 600; line-height: 22px; } .duplicate-section-title-description { margin-top: 2px; color: #999; font-size: 12px; font-weight: normal; line-height: 18px; } /* ========================================================== OPCIÓN ORIGEN ========================================================== */ .duplicate-source-wrapper { width: 100%; margin-bottom: 30px; } .duplicate-source-field { width: 290px; } .duplicate-source-field label { display: block; margin-bottom: 7px; color: #555; font-size: 13px; font-weight: 600; } .duplicate-source-field .form-control { width: 100%; height: 42px; padding: 8px 12px; border: 1px solid #dcdfe5; border-radius: 6px; box-shadow: none; } .duplicate-source-field .form-control:focus { border-color: #32aaf0; box-shadow: 0 0 0 2px rgba(50, 170, 240, 0.10); } /* ========================================================== SALAS DESTINO ========================================================== */ .duplicate-quote-wrapper { width: 100%; margin-bottom: 25px; } .duplicate-spaces { width: 100%; } /* ========================================================== ESPACIO ========================================================== */ .duplicate-space-card { width: 100%; margin-bottom: 10px; border: 1px solid #e1e4e8; border-radius: 8px; background: #fff; overflow: hidden; } /* ========================================================== CABECERA DEL ESPACIO ========================================================== */ .duplicate-space-header { position: relative; width: 100%; display: flex; align-items: center; justify-content: space-between; padding: 14px 18px; border: 0; background: #f8fafc; color: #101230; text-align: left; cursor: pointer; outline: none !important; } .duplicate-space-header:hover { background: #f1f5f9; } .duplicate-space-header:focus, .duplicate-space-header:active { outline: none !important; box-shadow: none !important; } .duplicate-space-title { display: flex; align-items: center; min-width: 0; gap: 9px; } .duplicate-space-title > i { flex-shrink: 0; color: #32aaf0; } .duplicate-space-count { display: inline-block; padding: 2px 8px; border-radius: 12px; background: #e9f5fd; color: #32aaf0; font-size: 11px; font-weight: 600; } .duplicate-space-chevron { flex-shrink: 0; color: #777; transition: transform 0.2s ease; } /* ========================================================== FLECHA AL ABRIR ========================================================== */ .duplicate-space-header[aria-expanded="true"] .duplicate-space-chevron { transform: rotate(180deg); } /* ========================================================== CONTENIDO DEL ESPACIO ========================================================== */ .duplicate-space-body { width: 100%; border-top: 1px solid #e8ebef; } /* ========================================================== CABECERA DE SALAS ========================================================== */ .duplicate-lounge-header { display: flex; align-items: center; min-height: 38px; padding: 8px 18px; background: #fafbfc; border-bottom: 1px solid #e8ebef; color: #777; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.4px; } /* ========================================================== FILA DE SALA ========================================================== */ .duplicate-lounge-row { display: flex; align-items: center; width: 100%; min-height: 58px; padding: 8px 18px; box-sizing: border-box; border-bottom: 1px solid #f0f1f3; transition: background 0.15s ease; } .duplicate-lounge-row:hover { background: #fafcff; } .duplicate-lounge-row:last-child { border-bottom: none; } /* ========================================================== COLUMNAS ========================================================== */ .duplicate-col-select { width: 100px; flex-shrink: 0; } .duplicate-col-name { flex: 1; min-width: 0; padding-right: 20px; } .duplicate-col-price { width: 220px; flex-shrink: 0; } /* ========================================================== CHECKBOX ========================================================== */ .duplicate-checkbox-wrapper { display: inline-flex; align-items: center; justify-content: center; margin: 0; cursor: pointer; } .duplicate-checkbox-wrapper input { margin: 0; width: 16px; height: 16px; cursor: pointer; } /* ========================================================== NOMBRE SALA ========================================================== */ .duplicate-lounge-name { display: block; margin: 0; color: #101230; font-size: 13px; font-weight: 500; line-height: 20px; cursor: pointer; } .duplicate-lounge-name:hover { color: #32aaf0; } /* ========================================================== PRECIO ========================================================== */ .duplicate-price-group { width: 100%; } .duplicate-price-group .form-control { height: 36px; border-radius: 6px 0 0 6px; border-color: #dcdfe5; box-shadow: none; } .duplicate-price-group .form-control:focus { border-color: #32aaf0; box-shadow: none; } .duplicate-price-group .input-group-addon { width: 42px; min-width: 42px; padding: 0; text-align: center; vertical-align: middle; background: #f8fafc; border: 1px solid #dcdfe5; border-left: 0; border-radius: 0 6px 6px 0; color: #555; font-weight: 600; } /* ========================================================== PRECIO DESHABILITADO ========================================================== */ .duplicate-lounge-price:disabled { background: #f5f6f8; cursor: not-allowed; color: #aaa; } /* ========================================================== ELIMINAR ORIGEN ========================================================== */ .duplicate-delete-wrapper { width: 100%; margin-top: 20px; } .duplicate-delete-wrapper .alert { margin-bottom: 0; } /* ========================================================== BOTÓN ========================================================== */ .duplicate-submit-wrapper { width: 100%; margin-top: 20px; text-align: right; } .duplicate-submit-wrapper button { min-width: 160px; } /* ========================================================== RESPONSIVE ========================================================== */ @media (max-width: 767px) { .duplicate-quote-container { padding-left: 10px; padding-right: 10px; } .duplicate-source-field { width: 100%; } .duplicate-col-select { width: 65px; } .duplicate-col-price { width: 150px; } .duplicate-lounge-row, .duplicate-lounge-header { padding-left: 10px; padding-right: 10px; } } </style> <div class="col-md-12" style="margin-top: 15px;"> <div class="col-md-11"></div> <div class="col-md-1 text-right"> <a href="{{ path('reservations_log_historic', { id: reserva.id }) }}" class="btn bg-btn-limerick btn-xs" title="Historico de Cotizaciones"> <i class="fa fa-book"></i> Registro </a> </div> </div> </div> </div> {% endif %} {# TOTALES SALAS (SOLO EN CONFIRMED O INVOICED) #} <div class="panel bg-rich_black text-mint_cream" style="margin: 0 300px 30px 300px"> <div class="panel-body text-center"> <div class="col-sm-12"> <div class="col-sm-4"> <h4>{% trans %}Salas con IVA{% endtrans %}</h4> <h3>{{ totales_global_con_iva|number_format(2, ',', '.') }} €</h3> </div> <div class="col-sm-4"> <h4>{% trans %}IVA Salas{% endtrans %}</h4> <h3>{{ totales_global_iva|number_format(2, ',', '.') }} €</h3> </div> <div class="col-sm-4"> <h4>{% trans %}Salas Neto{% endtrans %}</h4> <h3>{{ totales_global_neto|number_format(2, ',', '.') }} €</h3> </div> </div> </div> </div> {# SERVICIOS AÑADIDOS A LA RESERVA #} <div id="btn_srv" class="panel panel-default"> <div class="panel-body text-center"> <div class="col-sm-12"> <div class="row"> <div class="col-xs-12 text-center"> <h3><strong>{% trans %}Add Services to Reservation{% endtrans %}</strong></h3> </div> </div> <div class="col-sm-12 no-padding"> <div class="panel panel-default" style="border: none"> <div class="panel-body"> <div class="row text-center srv-icons"> <div class="col-xs-1 margen-10"> <form method="post" action="/venues/reservations/white/services/add/3/{{ id }}"> <button type="submit" class="btn-icon" title="{% trans %}Audiovisuales{% endtrans %}"> <img src="/assets/images/icon/audiovisuales.png" alt="{% trans %}Audiovisuales{% endtrans %}" height="80"> </button> </form> </div> <div class="col-xs-1 margen-10"> <form method="post" action="/venues/reservations/white/services/add/17/{{ id }}"> <button type="submit" class="btn-icon" title="{% trans %}Personal de Seguridad{% endtrans %}"> <img src="/assets/images/icon/seguridad.png" alt="{% trans %}Personal de Seguridad{% endtrans %}" height="80"> </button> </form> </div> <div class="col-xs-1 margen-10"> <form method="post" action="/venues/reservations/white/services/add/18/{{ id }}"> <button type="submit" class="btn-icon" title="{% trans %}WiFi{% endtrans %}"> <img src="/assets/images/icon/wifi.png" alt="{% trans %}WiFi{% endtrans %}" height="80"> </button> </form> </div> <div class="col-xs-1 margen-10"> <form method="post" action="/venues/reservations/white/services/add/15/{{ id }}"> <button type="submit" class="btn-icon" title="{% trans %}Project Manager{% endtrans %}"> <img src="/assets/images/icon/asistencia.png" alt="{% trans %}Project Manager{% endtrans %}" height="80"> </button> </form> </div> <div class="col-xs-1 margen-10"> <form method="post" action="/venues/reservations/white/services/add/11/{{ id }}"> <button type="submit" class="btn-icon" title="{% trans %}F&B (Catering){% endtrans %}"> <img src="/assets/images/icon/catering.png" alt="{% trans %}F&B (Catering){% endtrans %}" height="80"> </button> </form> </div> <div class="col-xs-1 margen-10"> <form method="post" action="/venues/reservations/white/services/add/21/{{ id }}"> <button type="submit" class="btn-icon" title="{% trans %}Limpieza{% endtrans %}"> <img src="/assets/images/icon/limpieza.png" alt="{% trans %}Limpieza{% endtrans %}" height="80"> </button> </form> </div> <div class="col-xs-1 margen-10"> <form method="post" action="/venues/reservations/white/services/add/20/{{ id }}"> <button type="submit" class="btn-icon" title="{% trans %}Parking{% endtrans %}"> <img src="/assets/images/icon/parking.png" alt="{% trans %}Parking{% endtrans %}" height="80"> </button> </form> </div> <div class="col-xs-1 margen-10"> <form method="post" action="/venues/reservations/white/services/add/19/{{ id }}"> <button type="submit" class="btn-icon" title="{% trans %}Mobiliario{% endtrans %}"> <img src="/assets/images/icon/mobiliario.png" alt="{% trans %}Mobiliario{% endtrans %}" height="80"> </button> </form> </div> <div class="col-xs-1 margen-10"> <form method="post" action="/venues/reservations/white/services/add/12/{{ id }}"> <button type="submit" class="btn-icon" title="{% trans %}Otros{% endtrans %}"> <img src="/assets/images/icon/otros.png" alt="{% trans %}Otros{% endtrans %}" height="80"> </button> </form> </div> </div> </div> </div> </div> {% if services is not empty %} {# Agrupación evaluando la propiedad 'rank' del objeto ReservationService #} {% set servicesGrouped = {} %} {% for service in services %} {% set rawQuoteId = (service.rank is defined and service.rank is not empty and service.rank != 0) ? service.rank : ((service.rankQuote is defined and service.rankQuote is not empty and service.rankQuote != 0) ? service.rankQuote : ((service.idQuote is defined and service.idQuote is not empty and service.idQuote != 0) ? service.idQuote : '0')) %} {% set groupKey = 'opt_' ~ rawQuoteId %} {% if servicesGrouped[groupKey] is not defined %} {% set servicesGrouped = servicesGrouped|merge({(groupKey): [service]}) %} {% else %} {% set servicesGrouped = servicesGrouped|merge({(groupKey): servicesGrouped[groupKey]|merge([service])}) %} {% endif %} {% endfor %} <form name="mds_venuesbundle_servicegrid" method="post" action="/venues/updateservicegrid/{{ id }}" class="form-horizontal" role="form" autocomplete="off"> <div class="col-sm-12" style="padding-left: 0px; padding-right: 0px"> {% for groupKey, groupServices in servicesGrouped %} {% set quoteId = groupKey|replace({'opt_': ''}) %} <!-- BLOQUE CONTENEDOR SEGMENTADO POR OPCIÓN --> <div class="panel panel-default" style="border: 1px solid #ded9e2; border-radius: 6px; margin-bottom: 30px; box-shadow: 0 2px 8px rgba(0,0,0,0.03);"> <div class="panel-heading" style="background-color: #f8f9fa; border-bottom: 2px solid #32aaf0; padding: 12px 20px;"> <h4 class="panel-title text-left" style="font-weight: bold; margin: 0;"> {% if quoteId != '0' %} <span class="label bg-btn-vivid_sky_blue" style="font-size: 13px; padding: 5px 10px; margin-right: 10px;"> <i class="icon-file-text2"></i> {% trans %}OPCIÓN{% endtrans %} #{{ quoteId }} </span> <span class="text-rich_black">{% trans %}Servicios asociados a la Opción{% endtrans %} #{{ quoteId }}</span> {% else %} <span class="label label-default" style="font-size: 13px; padding: 5px 10px; margin-right: 10px;"> <i class="icon-box"></i> {% trans %}SERVICIOS GENERALES{% endtrans %} </span> <span class="text-muted">{% trans %}Servicios sin opción específica asignada{% endtrans %}</span> {% endif %} </h4> </div> <div class="panel-body" style="padding: 20px 10px 10px 10px;"> {% for service in groupServices %} {% set currency = service.currency is empty ? 'Euro' : service.currency %} {% set contcolor = service.contcolor %} {% set error_commission = (service.commission is empty or service.commission == '0') ? 'has-error' : '' %} {% set error_over = (service.over is empty or service.over == '0') ? 'has-error' : '' %} {% set error_iva = (service.sageIva is empty or service.sageIva is null) ? 'has-error' : '' %} {% set option_opcommission = (service.opCommission == '0') ? '<option value="0" selected="selected">-</option><option value="1">+</option>' : '<option value="1" selected="selected">+</option><option value="0">-</option>' %} {% set option_opover = (service.opOver == '0') ? '<option value="0" selected="selected">-</option><option value="1">+</option>' : '<option value="1" selected="selected">+</option><option value="0">-</option>' %} {% set option_opiva = (service.opIva == '0') ? '<option value="0" selected="selected">-</option><option value="1">+</option>' : '<option value="1" selected="selected">+</option><option value="0">-</option>' %} {% set fondo_color = 'white' %} <div id="{{ service.id }}" class="panel panel-default border-left-{{ contcolor }} {{ fondo_color }} panel-collapsed" style="margin: 0 15px 20px 15px;"> <div class="panel-heading"> <div class="panel-title text-left"> <div class="row" style="display: flex; align-items: center; flex-wrap: wrap;"> <div class="col-xs-12 col-md-8"> {% if quoteId != '0' %} <span class="label bg-btn-vivid_sky_blue" style="margin-right: 8px; font-size: 11px;"> Opción #{{ quoteId }} </span> {% endif %} <b class="text-vivid_sky_blue"> {% trans %}Service{% endtrans %}: {% if not (service.serviceCatName|trans == 'Menú') %} {{ service.serviceCatName|trans }} {% else %} Catering {% endif %} {% if (service.name is not null) %} - {{ service.name }}{% endif %} </b> </div> <div class="col-xs-12 col-md-4 text-right"> {% if not service.toinvoice %} <small class="bg-trash text-white" style="padding: 4px 8px; border-radius: 3px;"> {{ 'EXPENSE'|trans({}) }} </small> {% endif %} </div> </div> </div> <div class="heading-elements"> <ul class="icons-list"> <li><a data-action="collapse"></a></li> </ul> </div> </div> {% if not (service.serviceCatId == 15) %} <div class="panel-body"> <div class="form-group"> <div class="col-sm-11"> <div class="col-sm-12"> <div class="col-sm-3" style="padding-bottom: 10px; padding-left: 0px;"> <label class="control-label">{% trans %}Supplier{% endtrans %}:</label> <div class="form-group form-group-material"> <select name="services[{{ service.id }}][supplier]" class="form-control" style="padding:0px;text-align-last: center;"> <option value="0">{% trans %}Select a Supplier{% endtrans %}</option> {% for supplier in listSupplier %} <option value="{{ supplier.id }}" {% if supplier.id == service.supplierId %}selected="selected"{% endif %}>{{ supplier.company }}</option> {% endfor %} </select> </div> </div> </div> <div class="col-sm-3"> <label class="control-label" for="services_name_{{ service.id }}">{% trans %}Description{% endtrans %}: </label> <input type="text" id="services_name_{{ service.id }}" name="services[{{ service.id }}][name]" value="{{ service.name }}" class="form-control"> </div> <div class="col-md-2 col-xs-12"> <label class="control-label" for="services_price_{{ service.id }}"> <span data-popup="tooltip-custom" title="{% trans %}Price with VAT or without VAT{% endtrans %}"> <b class="text-rich_black">{% trans %}Price{% endtrans %}</b>: </span> </label> <input type="text" id="services_price_{{ service.id }}" name="services[{{ service.id }}][price]" value="{{ service.price|number_format(2, ',', '.') }}" class="form-control bg-{{ contcolor }}-300"> </div> <div class="col-md-1 col-xs-6"> <label class="control-label" for="services_units_{{ service.id }}">{% trans %}Units{% endtrans %}: </label> <input type="number" id="services_units_{{ service.id }}" name="services[{{ service.id }}][units]" value="{{ service.units }}" class="form-control"> </div> <div class="col-md-1 col-xs-12"> <label class="control-label" for="services_pax_{{ service.id }}">{% trans %}Pax{% endtrans %}: </label> <input type="number" id="services_pax_{{ service.id }}" name="services[{{ service.id }}][pax]" value="{{ service.pax }}" class="form-control"> </div> <div class="col-md-5 col-xs-12"> <div class="col-md-2 col-xs-6 no-padding-right"> <label class="control-label" for="services_opcommission_{{ service.id }}">-/: </label> <div class="form-group form-group-material"> <select id="services_opcommission_{{ service.id }}" name="services[{{ service.id }}][opCommission]" class="form-control" style="padding:0px;text-align-last: center;"> {{ option_opcommission|raw }} </select> </div> </div> <div class="col-md-2 col-xs-6 no-padding-left"> <label class="control-label" for="services_commission_{{ service.id }}">{% trans %}Commission{% endtrans %}(%) </label> <div class="form-group form-group-material {{ error_commission }}"> <input type="text" id="services_commission_{{ service.id }}" name="services[{{ service.id }}][commission]" value="{{ service.commission|number_format(2, ',', '.') }}" class="form-control"> </div> </div> <div class="col-md-2 col-xs-6 no-padding-right" hidden> <select id="services_opover_{{ service.id }}" name="services[{{ service.id }}][opOver]" class="form-control" hidden> <option value="1" selected>+</option> <option value="0">-</option> </select> </div> <div class="col-md-2 col-xs-6 no-padding-left"> <label class="control-label" for="services_over_{{ service.id }}">{% trans %}Over{% endtrans %}(€) </label> <div class="form-group form-group-material {{ error_over }}"> <input type="text" id="services_over_{{ service.id }}" name="services[{{ service.id }}][over]" value="{{ service.over }}" class="form-control"> </div> </div> <div class="col-md-4 col-xs-6 no-padding-left"> <label class="control-label" for="services_iva_{{ service.id }}">{% trans %}Iva{% endtrans %}: </label> <div class="form-group form-group-material {{ error_iva }}"> <select id="services_iva_{{ service.id }}" name="services[{{ service.id }}][iva]" class="form-control" style="width: 100%;"> <option value="">Selecciona un IVA</option> {% for vat in sageVatRates %} <option value="{{ vat.id }}" {% if service.sageIva is not null and vat.id == service.sageIva.id %}selected{% endif %}> {{ vat.name }} ({{ vat.iva|number_format(2, '.', '') }}%) </option> {% endfor %} </select> </div> </div> </div> <div class="col-sm-9 margen-10"> <div class="col-sm-2 col-xs-6"> <label class="control-label" for="services_currency_{{ service.id }}">{% trans %}Currency{% endtrans %}: </label> <input type="text" id="services_currency_{{ service.id }}" name="services[{{ service.id }}][currency]" value="{{ currency }}" class="form-control"> </div> <div class="col-sm-2 no-padding"> <label class="control-label" for="services_start_{{ service.id }}"><i class="icon-watch2"></i> {% trans %}Star{% endtrans %}: </label> <input type="time" id="services_start_{{ service.id }}" name="services[{{ service.id }}][start]" value="{{ service.dateInAt|date('H:i') }}" class="form-control"> </div> <div class="col-sm-3"> <label class="control-label" for="services_dateInAt_{{ service.id }}">{% trans %}Date In{% endtrans %}: </label> <input type="date" id="services_dateInAt_{{ service.id }}" name="services[{{ service.id }}][dateInAt]" value="{{ service.dateInAt|date('Y-m-d') }}" class="form-control"> </div> <div class="col-sm-3"> <label class="control-label" for="services_dateOutAt_{{ service.id }}">{% trans %}Date Out{% endtrans %}: </label> <input type="date" id="services_dateOutAt_{{ service.id }}" name="services[{{ service.id }}][dateOutAt]" value="{{ service.dateOutAt|date('Y-m-d') }}" class="form-control"> </div> <div class="col-sm-2 no-padding"> <label class="control-label" for="services_hour_{{ service.id }}"><i class="icon-watch2"></i> {% trans %}End{% endtrans %}: </label> <input type="time" id="services_hour_{{ service.id }}" name="services[{{ service.id }}][end]" value="{{ service.dateOutAt|date('H:i') }}" class="form-control"> </div> </div> <div class="col-md-3" style="padding-top: 35px;"> <div class="checkbox-switchery text-left switchery-sm"> <label> <input type="checkbox" id="service_toinvoice_{{ service.id }}" name="services[{{ service.id }}][toinvoice]" class="switchery-info" value="1" {% if service.toinvoice %}checked{% endif %}/> {% trans %}Aparece en factura{% endtrans %} </label> </div> </div> <div class="col-md-3" style="padding-top: 35px;"> <div class="checkbox-switchery text-left switchery-sm"> <label> <input type="checkbox" id="service_viewInfo_{{ service.id }}" name="services[{{ service.id }}][viewinfo]" class="switchery-info" value="1" {% if service.viewInfo %}checked{% endif %}/> {% trans %}Add extra information to the web quotation{% endtrans %} </label> </div> </div> </div> <div class="col-sm-1 margen-5"> <div class="col-xs-12" style="padding-top: 15px; padding-left: 0px"> <div class="checkbox checkbox-switchery switchery-lg switchery-double text-center" title="Eliminar este item"> <a target="_self" class="btn bg-btn-trash btn-block icon-trash padding-3" onclick="return confirm('¿Deseas eliminar este elemento?');" href="/venues/deleteitemservice/{{ service.id }}/{{ id }}" title="Eliminar este elemento"></a> </div> </div> {% if (service.serviceCatId == 3) %} <div class="col-xs-12" style="padding-top: 15px; padding-left: 0px"> <a href="{{ path('reservations_list_multiple_productfile_av', { id: service.id }) }}" class="btn bg-btn-green_av btn-xs" title="Precios AVs"> <strong>Precios AVs</strong> </a> </div> {% endif %} </div> </div> </div> {% else %} {# ASISTENCIA #} <div class="panel-body"> <div class="form-group"> <div class="col-sm-3" style="padding-bottom: 10px; padding-left: 0px;"> <label class="control-label">{% trans %}Supplier{% endtrans %}:</label> <div class="form-group form-group-material"> <select name="services[{{ service.id }}][supplier]" class="form-control" style="padding:0px;text-align-last: center;"> <option value="0">{% trans %}Select a Supplier{% endtrans %}</option> {% for supplier in listSupplier %} <option value="{{ supplier.id }}" {% if supplier.id == service.supplierId %}selected="selected"{% endif %}>{{ supplier.company }}</option> {% endfor %} </select> </div> </div> <div class="col-sm-11"> <div class="col-sm-2" style="padding-bottom: 10px; padding-left: 0px;"> <label class="control-label" for="services_agent_{{ service.id }}">{% trans %}Agente{% endtrans %}:</label> <div class="form-group form-group-material"> <select id="services_agent_{{ service.id }}" name="services[{{ service.id }}][agent]" class="form-control" style="padding:0px;text-align-last: center;"> <option value="0">{% trans %}Selecciona un agente{% endtrans %}</option> {% for user in allUsersActive %} {% if (service.assistantId is not empty) and (user.id == service.assistantId or ((user.id * (-1)) == service.assistantId)) %} <option value="{{ user.role == 'Freelance' ? user.team : user.id }}" selected="selected">{{ user.name }} {{ user.lastname }}</option> {% else %} <option value="{{ user.role == 'Freelance' ? user.team : user.id }}">{{ user.name }} {{ user.lastname }}</option> {% endif %} {% endfor %} </select> </div> </div> <div class="col-sm-2"> <label class="control-label" for="services_name_{{ service.id }}">{% trans %}Title{% endtrans %}: </label> <input type="text" id="services_name_{{ service.id }}" name="services[{{ service.id }}][name]" value="{{ service.name }}" class="form-control"> </div> <div class="col-md-2 col-xs-12"> <label class="control-label" for="services_price_{{ service.id }}"> <span data-popup="tooltip-custom" title="{% trans %}Price with VAT or without VAT{% endtrans %}"> <b class="text-rich_black">{% trans %}Price{% endtrans %}</b>: </span> </label> <input type="text" id="services_price_{{ service.id }}" name="services[{{ service.id }}][price]" value="{{ service.price }}" class="form-control bg-{{ contcolor }}-300"> </div> <input type="hidden" id="services_currency_{{ service.id }}" name="services[{{ service.id }}][currency]" value="{{ currency }}" class="form-control"> <input type="hidden" id="services_units_{{ service.id }}" name="services[{{ service.id }}][units]" value="{{ service.units }}" class="form-control"> <input type="hidden" id="services_pax_{{ service.id }}" name="services[{{ service.id }}][pax]" value="{{ service.pax }}" class="form-control"> <div class="col-md-5 col-xs-12"> <div class="col-md-2 col-xs-6 no-padding-right"> <label class="control-label" for="services_opcommission_{{ service.id }}">-/: </label> <div class="form-group form-group-material"> <select id="services_opcommission_{{ service.id }}" name="services[{{ service.id }}][opCommission]" class="form-control" style="padding:0px;text-align-last: center;"> {{ option_opcommission|raw }} </select> </div> </div> <div class="col-md-2 col-xs-6 no-padding-left"> <label class="control-label" for="services_commission_{{ service.id }}">{% trans %}Commission{% endtrans %}: </label> <div class="form-group form-group-material {{ error_commission }}"> <input type="text" id="services_commission_{{ service.id }}" name="services[{{ service.id }}][commission]" value="{{ service.commission }}" class="form-control"> </div> </div> <div class="col-md-2 col-xs-6 no-padding-right"> <label class="control-label" for="services_opover_{{ service.id }}">-/: </label> <div class="form-group form-group-material"> <select id="services_opover_{{ service.id }}" name="services[{{ service.id }}][opOver]" class="form-control" style="padding:0px;text-align-last: center;"> {{ option_opover|raw }} </select> </div> </div> <div class="col-md-2 col-xs-6 no-padding-left"> <label class="control-label" for="services_over_{{ service.id }}">{% trans %}Over{% endtrans %}: </label> <div class="form-group form-group-material {{ error_over }}"> <input type="text" id="services_over_{{ service.id }}" name="services[{{ service.id }}][over]" value="{{ service.over }}" class="form-control"> </div> </div> <div class="col-md-2 col-xs-6 no-padding-right"> <label class="control-label" for="services_opiva_{{ service.id }}">-/: </label> <div class="form-group form-group-material"> <select id="services_opiva_{{ service.id }}" name="services[{{ service.id }}][opIva]" class="form-control" style="padding:0px;text-align-last: center;"> {{ option_opiva|raw }} </select> </div> </div> <div class="col-md-2 col-xs-6 no-padding-left"> <label class="control-label" for="services_iva_{{ service.id }}">{% trans %}Iva{% endtrans %}: </label> <div class="form-group form-group-material {{ error_iva }}"> <select id="services_iva_{{ service.id }}" name="services[{{ service.id }}][iva]" class="form-control" style="width: 100%;" required> <option value="">Selecciona un IVA</option> {% for vat in sageVatRates %} <option value="{{ vat.id }}" {% if service.sageIva is not null and vat.id == service.sageIva.id %}selected{% endif %}> {{ vat.name }} ({{ vat.iva|number_format(2, '.', '') }}%) </option> {% endfor %} </select> </div> </div> </div> <div class="col-sm-8 margen-10"> <div class="col-sm-2 no-padding"> <label class="control-label" for="services_start_{{ service.id }}"><i class="icon-watch2"></i> {% trans %}Star{% endtrans %}: </label> <input type="time" id="services_start_{{ service.id }}" name="services[{{ service.id }}][start]" value="{{ service.dateInAt|date('H:i') }}" class="form-control"> </div> <div class="col-sm-4"> <label class="control-label" for="services_dateInAt_{{ service.id }}">{% trans %}Date In{% endtrans %}: </label> <input type="date" id="services_dateInAt_{{ service.id }}" name="services[{{ service.id }}][dateInAt]" value="{{ service.dateInAt|date('Y-m-d') }}" class="form-control"> </div> <div class="col-sm-4"> <label class="control-label" for="services_dateOutAt_{{ service.id }}">{% trans %}Date Out{% endtrans %}: </label> <input type="date" id="services_dateOutAt_{{ service.id }}" name="services[{{ service.id }}][dateOutAt]" value="{{ service.dateOutAt|date('Y-m-d') }}" class="form-control"> </div> <div class="col-sm-2 no-padding"> <label class="control-label" for="services_hour_{{ service.id }}"><i class="icon-watch2"></i> {% trans %}End{% endtrans %}: </label> <input type="time" id="services_hour_{{ service.id }}" name="services[{{ service.id }}][end]" value="{{ service.dateOutAt|date('Y-m-d') }}" class="form-control"> </div> </div> <div class="col-md-4" style="padding-top: 35px;"> <div class="checkbox-switchery text-left switchery-sm"> <label> <input type="checkbox" id="service_viewInfo_{{ service.id }}" name="services[{{ service.id }}][viewinfo]" class="switchery-info" value="1" {% if service.viewInfo %}checked{% endif %}/> {% trans %}View Info{% endtrans %} </label> </div> </div> </div> <div class="col-sm-1 margen-5"> <div class="col-xs-12" style="padding-top: 15px; padding-left: 0px"> <div class="checkbox checkbox-switchery switchery-lg switchery-double text-center" title="Eliminar este item"> <a target="_self" class="btn bg-btn-trash btn-block icon-trash padding-3" onclick="return confirm('¿Deseas eliminar este elemento?');" href="/venues/deleteitemservice/{{ service.id }}/{{ id }}" title="Eliminar este elemento"></a> </div> </div> </div> </div> </div> {% endif %} </div> {% endfor %} </div> </div> {% endfor %} </div> <div class="col-md-4 col-md-offset-4 margen-20" style="padding-top: 5px; padding-left: 15px; padding-right: 15px"> <div class="form-group form-group-material"> <div class="text-center"> <button type="submit" id="mds_venuesbundle_servicegrid_save" name="mds_venuesbundle_servicegrid[save]" class="btn bg-btn-limerick btn-block">Guardar Servicios</button> </div> </div> </div> </form> {% endif %} </div> </div> </div> {# TOTALES SERVICIOS #} <div class="panel bg-rich_black text-mint_cream" style="margin: 0 300px 80px 300px"> <div class="panel-body text-center"> <div class="col-sm-12"> <div class="col-sm-4"> <h4>{% trans %}Servicios con IVA{% endtrans %}</h4> <h3>{{ totales_global_servicios_con_iva|number_format(2, ',', '.') }} €</h3> </div> <div class="col-sm-4"> <h4>{% trans %}IVA Servicios{% endtrans %}</h4> <h3>{{ totales_global_servicios_iva|number_format(2, ',', '.') }} €</h3> </div> <div class="col-sm-4"> <h4>{% trans %}Servicios Neto{% endtrans %}</h4> <h3>{{ totales_global_servicios_neto|number_format(2, ',', '.') }} €</h3> </div> </div> </div> </div> {# BENEFICIOS #} <div class="panel panel-default"> <div class="panel-body text-center"> <div class="col-sm-12"> <div class="col-sm-6"> <b class="text-gray-light">{% trans %}Beneficio{% endtrans %}</b> <br> <b> {{ benefit|number_format(2, ',', '.') }} €</b> </div> <div class="col-sm-6"> <b class="text-gray-light">{% trans %}Beneficio (%){% endtrans %}</b> <br> <b> {{ percBenefit|number_format(2, ',', '.') }} %</b> </div> <br><br><br> <div class="col-sm-12"> <b class="text-gray-light">{% trans %}Resumen de Beneficio{% endtrans %}</b> {% for lounge in payedLounges %} <br><b>{{ lounge.loungeName }} + {{ lounge.servicePrice|number_format(2, ',', '.') }} €</b> {% endfor %} {% for service in payedServices %} {# 1. Capturamos los valores una sola vez en variables puras de Twig #} {% set safe_price = service.price|default(0) %} {% set safe_over = service.over|default(0) %} {# 2. Hacemos el cálculo sobre las variables seguras #} <br><b>{{ service.name }} + {{ (safe_price + safe_over)|number_format(2, ',', '.') }} €</b> {% endfor %} {% for service in unPayedServices %} {% if service.toinvoice %} <br><b>{{ service.name }}</b> + {{ ((service.price|default(0) + 0) + (service.over|default(0) + 0))|number_format(2, ',', '.') }} € {% else %} <br><b>{{ service.name }}</b> - {{ ((service.price|default(0) + 0) + (service.over|default(0) + 0))|number_format(2, ',', '.') }} € {% endif %} {% endfor %} </div> </div> </div> </div> {# AGENDA #} <div class="panel panel-default"> <div class="panel-body"> <div class="col-sm-12"> <div class="panel"> <div class="panel-body"> <div class="col-md-12 col-xs-12"> <strong class="text-info"> <legend class="border-teal-800">{% trans %}AGENDA{% endtrans %}</legend> </strong> </div> <div class="col-sm-12"> <style> .agenda-container { background-color: #fff; border-radius: 4px; overflow: hidden; border: 1px solid #eee; } .agenda-row { display: flex; align-items: flex-start; padding: 4px 10px; border-bottom: 1px solid #f9f9f9; transition: all 0.1s ease; min-height: 32px; } .agenda-row:hover { background-color: #f5faff; } .agenda-row:last-child { border-bottom: none; } .agenda-content { flex: 1; min-width: 0; font-family: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; font-size: 13px; color: #444; line-height: 1.6; white-space: pre-wrap; word-wrap: break-word; } .agenda-row.header .agenda-content { font-weight: 700; color: #000; text-transform: uppercase; font-size: 12px; letter-spacing: 0.5px; padding-top: 5px; } .agenda-row.header-2 .agenda-content { font-weight: 600; color: #333; padding-left: 20px; } .agenda-row.header-3 .agenda-content { font-style: italic; color: #666; padding-left: 30px; } .agenda-row.day .agenda-content { font-weight: bold; color: #d9534f; padding-left: 30px; } .agenda-row.item .agenda-content { padding-left: 50px; } .agenda-actions { flex-shrink: 0; min-width: 140px; text-align: right; padding-left: 10px; } </style> <div class="agenda-container"> {% for linea in arregloLineasAgenda %} <div class="agenda-row {{ linea.type }}"> <div class="agenda-content">{{- linea.text -}}</div> <div class="agenda-actions"> {% if linea.id %} <div class="btn-group"> <button class="btn bg-btn-limerick btn-xs" data-toggle="modal" data-target="#modalEditar" title="Editar (Ref. {{ linea.numberLine }})" data-url="{{ path('reservation_agenda_item_edit', { id: linea.id }) }}"> <i class="fa fa-edit"></i> (Ref. {{ linea.numberLine }}) </button> <button class="btn bg-btn-vivid_sky_blue btn-xs" data-toggle="modal" data-target="#modalAgregarLinea" data-url="{{ path('reservation_agenda_item_duplicate', { id: linea.id }) }}" aria-label="Duplicar línea" title="Duplicar línea"> <i class="fa fa-copy"></i> </button> <a href="{{ path('reservation_agenda_item_delete', { id: linea.id }) }}" onclick="return confirm('¿Deseas eliminar la línea?');" class="btn bg-btn-trash btn-xs" title="Borrar"> <i class="fa fa-trash"></i> </a> </div> {% endif %} </div> </div> {% endfor %} </div> <div class="col-sm-12"><hr></div> <div class="col-sm-12 text-right margen-10"> <div class="btn-group"> <button class="btn bg-btn-limerick btn-sm" data-toggle="modal" data-target="#modalAgregarLinea" data-url="{{ path('reservation_agenda_item_add', { reservationId: id }) }}"> <i class="fa fa-plus"></i> Añadir línea </button> <a href="{{ path('reservation_agenda_print', { reservationId: id }) }}" target="_blank" class="btn bg-btn-vivid_sky_blue btn-sm"> <i class="fa fa-eye"></i> Ver Agenda </a> <a href="{{ path('reservations_agenda_pdf', { reservationId: id }) }}" target="_blank" class="btn bg-btn-limerick btn-sm"> <i class="fa fa-file-pdf-o"></i> Pdf Agenda </a> </div> </div> </div> </div> </div> </div> </div> </div> {# FACTURACIÓN #} <div class="panel panel-default"> <div class="panel-body"> <div class="col-xs-12"> <strong class="text-vivid_sky_blue"> <legend class="border-teal-800">{% trans %}FACTURACION{% endtrans %}</legend> </strong> </div> <div class="col-sm-12 text-center"> <div class="col-sm-12"> <div class="col-sm-1"><b>No.</b></div> <div class="col-sm-2"><b>Fecha de Facturación</b></div> <div class="col-sm-3"><b>Cliente</b></div> <div class="col-sm-1"><b>Neto</b></div> <div class="col-sm-1"><b>Iva</b></div> <div class="col-sm-1"><b>Total</b></div> <div class="col-sm-2"><b>Balance Restante</b></div> <div class="col-sm-1"><b>Acciones</b></div> </div> <div class="col-sm-12"><hr></div> {% set totalBalance = 0 %} {% for factura in facturas %} {% set totalBalance = totalBalance + factura.balance %} <div class="col-sm-12 margen-10"> <div class="col-sm-1"> {% if factura.type == 'Invoice' %} <p style="color: {{ factura.clientType == 'Supplier' ? 'orange' : 'inherit' }}">{{ factura.number }}</p> {% else %} <p style="color: {{ factura.type == 'Invoice Deposit' ? 'green' : 'red' }}"> {{ factura.number }} {% if factura.type != 'Invoice Deposit' %}({{ factura.invoiceToRec.number }}){% endif %} </p> {% endif %} </div> <div class="col-sm-2"> <p style="color: {{ factura.type == 'Invoice' ? (factura.clientType == 'Supplier' ? 'orange' : 'inherit') : (factura.type == 'Invoice Deposit' ? 'green' : 'red') }}"> {{ factura.dateAt|date("d/m/Y") }} </p> </div> <div class="col-sm-3"> <p style="color: {{ factura.type == 'Invoice' ? (factura.clientType == 'Supplier' ? 'orange' : 'inherit') : (factura.type == 'Invoice Deposit' ? 'green' : 'red') }}"> {{ factura.client.name|default('') }} </p> </div> <div class="col-sm-1"> <p style="color: {{ factura.type == 'Invoice' ? (factura.clientType == 'Supplier' ? 'orange' : 'inherit') : (factura.type == 'Invoice Deposit' ? 'green' : 'red') }}"> {{ factura.totalNet|number_format(2, ',', '.') }} </p> </div> <div class="col-sm-1"> <p style="color: {{ factura.type == 'Invoice' ? (factura.clientType == 'Supplier' ? 'orange' : 'inherit') : (factura.type == 'Invoice Deposit' ? 'green' : 'red') }}"> {{ factura.vat|number_format(2, ',', '.') }} </p> </div> <div class="col-sm-1"> <p style="color: {{ factura.type == 'Invoice' ? (factura.clientType == 'Supplier' ? 'orange' : 'inherit') : (factura.type == 'Invoice Deposit' ? 'green' : 'red') }}"> {{ factura.total|number_format(2, ',', '.') }} </p> </div> <div class="col-sm-2"> <p style="color: {{ factura.type == 'Invoice' ? (factura.clientType == 'Supplier' ? 'orange' : 'inherit') : (factura.type == 'Invoice Deposit' ? 'green' : 'red') }}"> {{ factura.balance|number_format(2, ',', '.') }} </p> </div> <div class="col-sm-1"> {% if factura.type == 'Invoice' %} <a class="btn bg-btn-vivid_sky_blue btn-xs" href="/venues/reservations/invoice/viewnew/{{ factura.id }}">{% trans %}Go{% endtrans %}</a> {% elseif factura.type == 'Invoice Deposit' %} <a class="btn bg-btn-vivid_sky_blue btn-xs" href="/venues/reservations/newinvoicedeposit/viewinvoicedeposit/{{ factura.id }}">{% trans %}Go{% endtrans %}</a> {% elseif factura.type == 'Invoice Rec' %} <a class="btn bg-btn-vivid_sky_blue btn-xs" href="/venues/reservations/invoice/viewrec/{{ factura.id }}">{% trans %}Go{% endtrans %}</a> {% elseif factura.type == 'Invoice Deposit Rec' %} <a class="btn bg-btn-vivid_sky_blue btn-xs" href="/venues/reservations/newinvoicedeposit/viewinvoicedepositrec/{{ factura.id }}">{% trans %}Go{% endtrans %}</a> {% endif %} </div> </div> {% endfor %} {% for item in paymentNotIvoiced %} {% if item.invoiceId is empty %} {% set totalBalance = totalBalance - item.Amount %} {% endif %} <div class="col-sm-12 margen-10"> <div class="col-sm-1"></div> <div class="col-sm-2"><p style="color:blue">{{ item.DatePayAt|date("d/m/Y") }}</p></div> <div class="col-sm-3"><p style="color:blue">{{ item.WayToPay }}</p></div> <div class="col-sm-1"></div> <div class="col-sm-1"></div> <div class="col-sm-1"></div> <div class="col-sm-2"> <p style="color:blue">-{{ (item.invoiceId is empty ? item.Amount : item.AmountTotal)|number_format(2, ',', '.') }}</p> </div> <div class="col-sm-1"></div> </div> {% endfor %} <div class="col-sm-12"><hr></div> <div class="col-sm-12"> <div class="col-sm-offset-6 col-sm-1"><b>Neto</b><br>{{ resultados.totalNeto|number_format(2, ',', '.') }}</div> <div class="col-sm-1"><b>Iva</b><br>{{ resultados.vat|number_format(2, ',', '.') }}</div> <div class="col-sm-1"><b>Total</b><br>{{ resultados.total|number_format(2, ',', '.') }}</div> <div class="col-sm-2"><b>Balance Restante</b><br>{{ totalBalance|number_format(2, ',', '.') }}</div> </div> </div> </div> </div> {# PROFORMAS DE RESERVA #} <div class="panel panel-default"> <div class="panel-body"> <div class="col-xs-12"> <strong class="text-vivid_sky_blue"> <legend class="border-teal-800">{% trans %}PROFORMAS DE RESERVA{% endtrans %}</legend> </strong> </div> <div class="col-sm-12 text-center"> <div class="col-sm-12"> <div class="col-sm-4"><b>{% trans %}Numero de Proforma{% endtrans %}</b></div> <div class="col-sm-4"><b>{% trans %}Fecha de Creación{% endtrans %}</b></div> <div class="col-sm-4"><b>{% trans %}Acciones{% endtrans %}</b></div> </div> <div class="col-sm-12"><hr></div> {% for proforma in allReservationProformas %} <div class="col-sm-12 margen-10"> <div class="col-sm-4"><p style="color:blue">{{ proforma.prefix }}</p></div> <div class="col-sm-4">{{ proforma.createdAt|date("d/m/Y") }}</div> <div class="col-sm-4"> <a class="btn bg-btn-vivid_sky_blue btn-xs" href="{{ path('reservations_viewnew_proforma', {'id': proforma.id}) }}">{% trans %}Go{% endtrans %}</a> </div> </div> {% else %} <div class="col-sm-12 margen-10 text-muted">{% trans %}Sin proformas asociadas a esta reserva.{% endtrans %}</div> {% endfor %} </div> </div> </div> {# DEPÓSITOS PROFORMA #} <div class="panel panel-default"> <div class="panel-body"> <div class="col-xs-12"> <strong class="text-vivid_sky_blue"> <legend class="border-teal-800">{% trans %}DEPÓSITOS PROFORMA{% endtrans %}</legend> </strong> </div> <div class="col-sm-12 text-center" style="margin-top:20px;"> <div class="col-sm-12"> <div class="col-sm-2"><b>Numero de Proforma</b></div> <div class="col-sm-2"><b>Fecha del Depósito</b></div> <div class="col-sm-3"><b>Monto</b></div> <div class="col-sm-3"><b>Pendiente</b></div> <div class="col-sm-2"><b>Acciones</b></div> </div> <div class="col-sm-12"><hr></div> {% for proforma in proformas %} {% set total = proforma.total|default(0) %} {% set paid = sumsByProforma[proforma.id].paid|default(0) %} {% set remaining = (total - paid) %} <div class="col-sm-12 margen-10"> <div class="col-sm-2">{{ proforma.number }}</div> <div class="col-sm-2">{{ proforma.dateAt|date('d/m/Y') }}</div> <div class="col-sm-3">{{ total|number_format(2, ',', '.') }}</div> <div class="col-sm-3">{{ remaining|number_format(2, ',', '.') }}</div> <div class="col-sm-2"> {% set anyDeposit = proforma.deposits|first %} <button class="btn bg-btn-vivid_sky_blue js-show-payments" data-deposit-id="{{ anyDeposit.id }}" data-url="{{ path('deposit_payments_modal', { id: anyDeposit.id }) }}" data-toggle="modal" data-target="#paymentsModal"> Pagos </button> </div> </div> {% endfor %} {% for depósito in depositsAll %} {% if depósito.proformaDeposit is null %} <div class="col-sm-12 margen-10"> <div class="col-sm-2">N/A</div> <div class="col-sm-2">{{ depósito.date|date('d/m/Y') }}</div> <div class="col-sm-3">{{ depósito.amount|number_format(2, ',', '.') }}</div> <div class="col-sm-3">0</div> <div class="col-sm-2"> <button class="btn bg-btn-vivid_sky_blue js-show-payments" data-deposit-id="{{ depósito.id }}" data-url="{{ path('deposit_payments_modal', { id: depósito.id }) }}" data-toggle="modal" data-target="#paymentsModal"> Pagos </button> </div> </div> {% endif %} {% endfor %} </div> </div> </div> {# PAYMENTS #} <div class="panel panel-default"> <div class="panel-body"> <div class="col-xs-12"> <strong class="text-vivid_sky_blue"> <legend class="border-teal-800">{% trans %}Payments{% endtrans %}</legend> </strong> </div> <div class="col-sm-12 text-center"> <div class="col-sm-12"> <div class="col-sm-3"><b>Expediente</b></div> <div class="col-sm-3"><b>Fecha de Pago</b></div> <div class="col-sm-3"><b>Forma de Pago</b></div> <div class="col-sm-3"><b>Monto</b></div> </div> <div class="col-sm-12"><hr></div> <div class="row"> {% for payment in paymentsAll %} <div class="col-sm-12 margen-10"> <div class="row"> <div class="col-sm-3">{{ payment.reservationId }}</div> <div class="col-sm-3">{{ payment.datePayAt|date('d/m/Y') }}</div> <div class="col-sm-3">{{ payment.wayToPay }}</div> <div class="col-sm-3">{{ payment.amount|number_format(2, ',', '.') }}</div> </div> </div> {% endfor %} </div> </div> </div> </div> </div> </div> </div> </div></div>{# MODALES #}<div class="modal fade" id="paymentsModal" tabindex="-1" role="dialog" aria-labelledby="paymentsModalLabel"> <div class="modal-dialog modal-lg" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Cerrar"><span aria-hidden="true">×</span></button> <h4 class="modal-title" id="paymentsModalLabel">Pagos</h4> </div> <div class="modal-body"> <p class="text-muted" id="paymentsModalLoading">Cargando…</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button> </div> </div> </div></div><div class="modal fade" id="modalEditar" tabindex="-1" role="dialog"> <div class="modal-dialog modal-lg" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">Editar línea de la agenda</h5> <button type="button" class="close" data-dismiss="modal"><span>×</span></button> </div> <div class="modal-body"> <div id="modalEditarContenido">Cargando...</div> </div> </div> </div></div><div class="modal fade" id="modalAgregarLinea" tabindex="-1" role="dialog"> <div class="modal-dialog modal-lg" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">Añadir línea a la agenda</h5> <button type="button" class="close" data-dismiss="modal"><span>×</span></button> </div> <div class="modal-body"> <div id="modalAgregarContenido">Cargando formulario ...</div> </div> </div> </div></div><div id="tracingsModal" class="modal fade" role="dialog"> <div class="modal-dialog modal-lg"> <div class="modal-content"> <div class="modal-header bg-btn-limerick"> <button type="button" class="close" data-dismiss="modal">×</button> <h5 class="modal-title"><i class="icon-history position-left"></i> Gestión de Seguimientos</h5> </div> <div class="modal-body"> <div class="panel panel-body"> <h6 style="margin-top:0;">Añadir nuevo seguimiento</h6> <form id="ajax-tracing-form" onsubmit="submitTracingAjax(event)"> <div class="row"> <div class="col-sm-4"> <div class="form-group"> <label>Fecha de aviso a futuro</label> <div class="input-group"> <span class="input-group-addon"><i class="icon-calendar22"></i></span> <input type="date" id="tracingDateAjax" class="form-control" required /> </div> </div> </div> <div class="col-sm-6"> <div class="form-group"> <label>Texto recordatorio</label> <input type="text" id="tracingTextAjax" class="form-control" placeholder="Escribe tu recordatorio..." required /> </div> </div> <div class="col-sm-2"> <div class="form-group"> <label> </label> <button type="submit" class="btn bg-btn-limerick btn-block" id="btn-save-tracing">Guardar</button> </div> </div> </div> </form> </div> <h6 class="text-semibold"><i class="icon-list3 position-left"></i> Historial de Seguimientos Planificados</h6> <div id="tracing-history-container"> {% if tracings|length > 0 %} <div class="table-responsive"> <table class="table table-bordered table-striped text-size-small"> <thead> <tr class="bg-light"> <th style="width: 15%">Fecha Aviso</th> <th style="width: 65%">Mensaje</th> <th style="width: 20%">Registro</th> </tr> </thead> <tbody> {% for tracing in tracings %} <tr> <td> <span class="label text-vivid_sky_blue label-block"> <i class="icon-calendar3 position-left" style="font-size:10px;"></i> {{ tracing.dateAt|date('d-m-Y') }} </span> </td> <td>{{ tracing.text }}</td> <td><span class="text-muted"><i class="icon-clock3 position-left text-size-mini"></i>{{ tracing.createdAt|date('d-m-Y H:i') }}</span></td> </tr> {% endfor %} </tbody> </table> </div> {% else %} <div class="alert alert-info" style="margin-bottom:0;"> No hay seguimientos registrados para esta reserva. </div> {% endif %} </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Cerrar ventana</button> </div> </div> </div></div><div class="modal fade" id="modalReschedule" tabindex="-1" role="dialog" aria-labelledby="modalRescheduleLabel"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header bg-btn-vivid_sky_blue text-white"> <button type="button" class="close" data-dismiss="modal" aria-label="Cerrar"><span aria-hidden="true">×</span></button> <h4 class="modal-title" id="modalRescheduleLabel"><i class="icon-calendar position-left"></i> {% trans %}Reprogramar Fechas del Evento{% endtrans %}</h4> </div> <div class="modal-body"> <div class="form-group"> <label class="control-label" for="newStartDate">{% trans %}Nueva Fecha de Inicio del Evento{% endtrans %}</label> <input type="date" class="form-control" id="newStartDate" name="newStartDate"> <span class="help-block text-muted"> <i class="icon-info22 text-vivid_sky_blue"></i> {% trans %}Al cambiar esta fecha, todas las fechas de finalización, salas y servicios se desplazarán exactamente en la misma cantidad de días.{% endtrans %} </span> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">{% trans %}Cancelar{% endtrans %}</button> <button type="button" class="btn bg-btn-limerick" id="btnConfirmReschedule">{% trans %}Aceptar{% endtrans %}</button> </div> </div> </div></div><div class="modal fade" id="modalWebObservations" tabindex="-1" role="dialog" aria-labelledby="modalWebObservationsLabel"> <div class="modal-dialog modal-lg" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title" id="modalWebObservationsLabel"> <i class="fa fa-comments-o"></i> Observaciones cliente </h4> </div> <div class="modal-body" style="max-height: 450px; overflow-y: auto;"> {% if webObservations is not empty %} {% for obs in webObservations %} <div class="panel panel-default"> <div class="panel-heading" style="background-color: #f5f5f5;"> <strong class="text-primary"><i class="fa fa-calendar"></i> {{ obs.createdAt|date('d/m/Y H:i:s') }}</strong> </div> <div class="panel-body"> <p style="white-space: pre-wrap; margin: 0;">{{ obs.observation }}</p> </div> </div> {% endfor %} {% else %} <div class="well text-center" style="margin-bottom: 0;"> <p class="text-muted" style="margin: 0;"> <i class="fa fa-info-circle fa-lg"></i> No se han recibido observaciones desde la cotización web para esta propuesta todavía. </p> </div> {% endif %} </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button> </div> </div> </div></div>{% endblock %}{% block javascripts %} {{ parent() }} <script type="text/javascript" src="{{ asset('assets/js/plugins/editors/summernote/summernote.min.js') }}"></script> <script type="text/javascript" src="{{ asset('assets/js/plugins/croppie/croppie.js') }}"></script> <script type="text/javascript" src="{{ asset('assets/js/plugins/forms/styling/switchery.min.js') }}"></script> <script type="text/javascript" src="{{ asset('assets/js/plugins/loaders/blockui.min.js') }}"></script> <script type="text/javascript" src="{{ asset('assets/js/plugins/forms/selects/select2.min.js') }}"></script> <script type="text/javascript" src="{{ asset('assets/js/pages/venues/add-simple-reservation.js') }}"></script> <script type="text/javascript" src="{{ asset('assets/js/pages/venues/services-invoice-select-items.js') }}"></script> <script type="text/javascript" src="{{ asset('assets/js/pages/venues/switchery-services.js') }}"></script> <script> $(document).ready(function() { $('.select2').select2({ width: '100%' }); $('.summernote-small').summernote({ height: 150, minHeight: 150, maxHeight: 150, disableResizeEditor: true, // AGREGAMOS LA BARRA DE HERRAMIENTAS: toolbar: [ // [nombre_del_grupo, [lista_de_botones]] ['style', ['style']], ['font', ['bold', 'underline', 'clear']], ['fontname', ['fontname']], ['fontsize', ['fontsize']], ['color', ['color']], ['para', ['ul', 'ol', 'paragraph']], ['table', ['table']], ['insert', ['link', 'picture', 'video']], ['view', ['fullscreen', 'codeview', 'help']] ], // Puedes definir los tamaños exactos que quieres que aparezcan en el desplegable del fontsizes fontSizes: ['8', '9', '10', '11', '12', '14', '16', '18', '24', '36', '48'] }); const $inputDias = $('#reservation_daysBlock'); const $inputFecha = $('#days'); const $selectStatus = $('#mds_venuesbundle_reservation_status'); function updateFechaDesdeDias() { let n = parseInt($inputDias.val(), 10); if (isNaN(n)) return; let d = new Date(); d.setHours(0,0,0,0); d.setDate(d.getDate() + n); let iso = d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') + '-' + String(d.getDate()).padStart(2, '0'); $inputFecha.val(iso); } function updateDiasDesdeFecha() { let str = $inputFecha.val(); if (!str) return; let seleccionada = new Date(str); let hoy = new Date(); hoy.setHours(0,0,0,0); let diffTime = seleccionada - hoy; let diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); $inputDias.val(diffDays >= 0 ? diffDays : 0); } window.recalculateDeadline = updateFechaDesdeDias; $inputDias.on('input change', updateFechaDesdeDias); $inputFecha.on('change', updateDiasDesdeFecha); if($selectStatus.val() !== 'BLOQUEO') { updateFechaDesdeDias(); } const steps = document.querySelectorAll('#estado-stepper .step'); const stepperContainer = document.querySelector('#estado-stepper'); if (stepperContainer && $selectStatus.length > 0) { const estadoIndex = parseInt(stepperContainer.dataset.estadoIndex); steps.forEach((step, index) => { if (index <= estadoIndex) { setTimeout(() => { if (index < estadoIndex) { step.classList.add('completed'); } else if (index === estadoIndex) { step.classList.add('active'); } }, index * 250); } step.addEventListener('click', (e) => { if (step.classList.contains('disabled')) { e.preventDefault(); return; } const newStatusLabel = $(step).find('span').text().trim().toUpperCase(); const $option = $selectStatus.find('option').filter(function() { return $(this).text().trim().toUpperCase() === newStatusLabel; }); if ($option.length && !$option.prop('disabled')) { $selectStatus.val($option.val()); $selectStatus.closest('form').submit(); } }); }); } $('#modalEditar, #modalAgregarLinea').on('show.bs.modal', function (event) { var button = $(event.relatedTarget); var url = button.data('url'); var modal = $(this); var contentDiv = modal.find('.modal-body > div'); contentDiv.html("<p class='text-muted'>Cargando...</p>"); $.ajax({ url: url, success: function(data) { contentDiv.html(data); }, error: function() { contentDiv.html("<div class='alert alert-danger'>Error al cargar el contenido.</div>"); } }); }); $(document).on('click', '.js-show-payments', function (e) { e.preventDefault(); var $btn = $(this); var $modal = $('#paymentsModal'); $modal.find('.modal-title').text('Pagos del depósito #' + $btn.data('deposit-id')); $modal.find('.modal-body').html('<p class="text-muted">Cargando…</p>'); $.get($btn.data('url')) .done(function (html) { $modal.find('.modal-body').html(html); }) .fail(function () { $modal.find('.modal-body').html('<div class="alert alert-danger">Error al cargar pagos.</div>'); }); }); }); var changeLanguageUrlTemplate = '{{ path("reservations_venues_change_language", { "id": "ID_PLACEHOLDER", "idLanguage": "LANG_PLACEHOLDER" }) }}'; function changeLanguageWeb(idLanguage) { if (confirm("¿Está seguro de que desea cambiar el idioma? Se perderán todos los cambios del idioma actual.")) { var changeLanguageUrl = changeLanguageUrlTemplate .replace('ID_PLACEHOLDER', {{ id }}) .replace('LANG_PLACEHOLDER', idLanguage); $.ajax({ url: changeLanguageUrl, type: 'GET', dataType: 'json', success: function(response) { if (response.status == 200) { $('#reservation_global_lounge_language_hidden').val(idLanguage); $.each(response.idiomas, function(key, data) { if (data !== null) { $('.resumenDescriptivo-' + key + '-editor').each(function () { $(this).summernote('code', data.importantDescription); }); $('.general-' + key + '-editor').each(function () { $(this).summernote('code', data.importantDescGeneralText); }); $('.horarios-' + key + '-editor').each(function () { $(this).summernote('code', data.importantDescSchedules); }); $('.parking-' + key + '-editor').each(function () { $(this).summernote('code', data.importantDescParking); }); } }); } else { console.error("Error al cambiar el idioma:", response.statusText); } }, error: function(xhr, status, error) { console.error("Error al cambiar el idioma:", error); } }); } else { var previousLang = $('#reservation_global_lounge_language_hidden').val(); $('#reservation_idWebLanguage').val(previousLang); return false; } } function submitTracingAjax(e) { e.preventDefault(); var dateVal = $("#tracingDateAjax").val(); var textVal = $("#tracingTextAjax").val(); if(!dateVal || !textVal) { alert("Rellena ambos campos obligatorios."); return; } var btn = $("#btn-save-tracing"); btn.button('loading'); $.ajax({ url: "/venues/tracing/add/{{ id }}", type: "POST", data: { tracingDate: dateVal, tracingText: textVal }, success: function(res) { btn.button('reset'); if(res.status === 'ok') { $("#tracingDateAjax").val(''); $("#tracingTextAjax").val(''); swal({ title: "¡Guardado!", text: "El seguimiento se ha guardado correctamente.", type: "success", confirmButtonColor: "#2196F3", timer: 1500 }); setTimeout(function() { location.reload(); }, 1500); } else { swal("Error", "No se pudo guardar el seguimiento.", "error"); } }, error: function() { btn.button('reset'); swal("Error", "Ocurrió un error en la conexión.", "error"); } }); } $(document).on('blur change', 'input[name*="End"], input[id^="end_"], input[name*="hourEnd"]', function() { var $input = $(this); var valor = $input.val().trim(); if (valor === "00:00" || valor === "00.00" || valor === "0" || valor === "00" || valor === "000" || valor === "0000") { $input.val("23:59"); var $parent = $input.closest('.col-md-1, .form-group'); $parent.addClass('has-warning'); setTimeout(function() { $parent.removeClass('has-warning'); }, 2000); } }); $(document).ready(function() { $('[data-toggle="tooltip"]').tooltip(); }); document.addEventListener("DOMContentLoaded", function () { const $salaSelect = $('#reservation_sala_salasPrecargadas'); const $dateInput = $('#reservation_sala_date'); const $priceInput = $('#reservation_sala_servicePrice'); function fetchPrice() { const salaId = $salaSelect.val(); const date = $dateInput.val(); if (salaId && date) { fetch('{{ path("get_reservations_price_to_view") }}?sala=' + salaId + '&date=' + date) .then(response => { if (!response.ok) throw new Error("HTTP error " + response.status); return response.json(); }) .then(data => { if (data.price !== undefined) { $priceInput.val(data.price); } else { $priceInput.val(""); } }) .catch(err => console.error("Error obteniendo precio:", err)); } } $salaSelect.on("change", fetchPrice); $dateInput.on("change", fetchPrice); }); document.addEventListener("DOMContentLoaded", function () { function diffDays(d1, d2) { var a = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate()); var b = new Date(d2.getFullYear(), d2.getMonth(), d2.getDate()); return Math.round((b - a) / 86400000); } var mainDateStartValue = '{{ reserva.dateStart ? reserva.dateStart|date("Y-m-d") : "" }}'; var mainDateEndValue = '{{ reserva.dateEnd ? reserva.dateEnd|date("Y-m-d") : "" }}'; function superaLos30Dias(fechaSala) { if (!mainDateStartValue || mainDateStartValue.trim() === "") return false; var ds = new Date(mainDateStartValue); if (mainDateEndValue && mainDateEndValue.trim() !== "") { var de = new Date(mainDateEndValue); if (!isNaN(ds.getTime()) && !isNaN(de.getTime()) && de < ds) { return false; } } var dt = new Date(fechaSala); if (!isNaN(ds.getTime()) && !isNaN(dt.getTime())) { if (Math.abs(diffDays(ds, dt)) > 30) return true; } return false; } var formSalasPre = document.forms['mds_venuesbundle_revervation_form2']; if (formSalasPre) { formSalasPre.addEventListener('submit', function (e) { var salaDateInput = document.getElementById('reservation_sala_date'); if (salaDateInput && salaDateInput.value.trim() !== "") { if (superaLos30Dias(salaDateInput.value)) { e.preventDefault(); alert("{% trans %}Error: La diferencia entre la fecha de inicio del expediente y la fecha de la sala precargada no puede superar los 30 días.{% endtrans %}"); } } }); } var formLoungeGrid = document.forms['mds_venuesbundle_loungrid']; if (formLoungeGrid) { formLoungeGrid.addEventListener('submit', function (e) { var gridDateInputs = formLoungeGrid.querySelectorAll('input[type="date"][id^="newDate_"]'); var gridTieneErrores = false; for (var i = 0; i < gridDateInputs.length; i++) { var currentVal = gridDateInputs[i].value; if (currentVal.trim() !== "") { if (superaLos30Dias(currentVal)) { gridTieneErrores = true; gridDateInputs[i].style.borderColor = '#F44336'; } else { gridDateInputs[i].style.borderColor = ''; } } } if (gridTieneErrores) { e.preventDefault(); alert("{% trans %}Error: Hay salas en la cotización cuya fecha supera los 30 días de diferencia respecto a la fecha de inicio del expediente. Por favor, revise las casillas marcadas en rojo.{% endtrans %}"); } }); } }); $(document).ready(function() { $('#btnConfirmReschedule').on('click', function() { var newDate = $('#newStartDate').val(); if (!newDate) { swal("Atención", "Debe seleccionar una nueva fecha de inicio.", "warning"); return; } swal({ title: "¿Está seguro?", text: "Se modificarán las fechas de la reserva, todas las salas y los servicios asociados. Esta acción recalculará los días para todos los elementos.", type: "warning", showCancelButton: true, confirmButtonColor: "#32aaf0", confirmButtonText: "Sí, reprogramar", cancelButtonText: "Cancelar", closeOnConfirm: false, showLoaderOnConfirm: true }, function(isConfirm) { if (isConfirm) { $('#modalReschedule').modal('hide'); $.ajax({ url: "/venues/reschedule/{{ id }}/" + newDate, type: "POST", success: function(response) { if(response.status === 'success') { swal({ title: "¡Éxito!", text: response.message, type: "success", confirmButtonColor: "#2196F3" }, function() { location.reload(); }); } else { swal("Error", response.message, "error"); } }, error: function(xhr) { var errorMsg = "Ocurrió un error al comunicarse con el servidor."; if(xhr.responseJSON && xhr.responseJSON.message) { errorMsg = xhr.responseJSON.message; } swal("Error", errorMsg, "error"); } }); } }); }); // Modal de Contratos Firmados del Expediente $('#btn-open-signed-contracts').on('click', function(e) { e.preventDefault(); $('#modal-reservation-signed-contracts').modal('show'); $('#signed-contracts-table-container').html( '<div class="text-center text-muted" style="padding: 30px 0;">' + '<i class="glyphicon glyphicon-refresh glyphicon-refresh-animate"></i> Cargando contratos firmados...' + '</div>' ); $.ajax({ url: '{{ path('reservations_signed_contracts_list', {'id': id}) }}', type: 'GET', success: function(resp) { if (resp.status === 'success' && resp.signedContracts) { if (resp.signedContracts.length === 0) { $('#signed-contracts-table-container').html( '<div class="alert alert-info text-center" style="font-size: 12px; margin: 15px 0;">' + '<i class="icon-info22 position-left"></i> Aún no se ha registrado ningún contrato firmado formalmente para este expediente.' + '</div>' ); return; } var html = '<div class="table-responsive"><table class="table table-hover table-striped table-bordered" style="background: #fff; font-size: 12px;">' + '<thead style="background: #101230; color: #fff;">' + '<tr>' + '<th>Tipo / Espacio</th>' + '<th style="width: 80px; text-align: center;">Versión</th>' + '<th>Firmante</th>' + '<th>Fecha y Hora</th>' + '<th style="text-align: center;">Estado</th>' + '<th style="width: 140px; text-align: center;">Acciones</th>' + '</tr>' + '</thead>' + '<tbody>'; $.each(resp.signedContracts, function(idx, item) { var badge = item.isCurrentValid ? '<span class="label label-success" style="background-color: #27ae60; font-size: 11px;"><i class="icon-checkmark3 position-left"></i> VIGENTE</span>' : '<span class="label label-default" style="background-color: #95a5a6; font-size: 11px;"><i class="icon-history position-left"></i> Histórico</span>'; var rowStyle = item.isCurrentValid ? 'font-weight: 500; background-color: #f0fdf4;' : ''; var downloadBtn = item.pdfUrl ? '<a href="' + item.pdfUrl + '" target="_blank" class="btn btn-xs ' + (item.isCurrentValid ? 'btn-success' : 'btn-default') + '" style="font-weight: bold;">' + '<i class="icon-download position-left"></i> Descargar PDF' + '</a>' : '<span class="text-muted">-</span>'; html += '<tr style="' + rowStyle + '">' + '<td><strong>' + (item.modelTitle || 'Contrato') + '</strong></td>' + '<td style="text-align: center;"><span class="badge" style="background-color: #32aaf0;">v' + item.versionNumber + '</span></td>' + '<td>' + (item.signedByName || '-') + (item.signedByJob ? ' <small class="text-muted">(' + item.signedByJob + ')</small>' : '') + '</td>' + '<td>' + (item.signedAt || '-') + '</td>' + '<td style="text-align: center;">' + badge + '</td>' + '<td style="text-align: center;">' + downloadBtn + '</td>' + '</tr>'; }); html += '</tbody></table></div>'; $('#signed-contracts-table-container').html(html); } else { $('#signed-contracts-table-container').html('<div class="alert alert-danger" style="font-size: 12px;">Error al cargar los contratos firmados.</div>'); } }, error: function() { $('#signed-contracts-table-container').html('<div class="alert alert-danger" style="font-size: 12px;">Error de comunicación con el servidor.</div>'); } }); }); }); </script> <script> document.addEventListener('DOMContentLoaded', function () { /* ====================================================== ACTIVAR / DESACTIVAR PRECIO ====================================================== */ document.querySelectorAll('.duplicate-lounge-check').forEach(function (checkbox) { checkbox.addEventListener('change', function () { var loungeId = this.id.replace( 'duplicate_lounge_', '' ); var priceInput = document.querySelector( 'input[name="addquote[salas][' + loungeId + '][price]"]' ); if (!priceInput) { return; } priceInput.disabled = !this.checked; if (this.checked) { priceInput.focus(); } else { priceInput.value = ''; } }); }); /* ====================================================== ACTUALIZAR ARIA DE LOS COLLAPSE ====================================================== */ $('.duplicate-space-card .collapse').on( 'show.bs.collapse', function () { var button = $(this).prev( '.duplicate-space-header' ); button.attr( 'aria-expanded', 'true' ); } ); $('.duplicate-space-card .collapse').on( 'hide.bs.collapse', function () { var button = $(this).prev( '.duplicate-space-header' ); button.attr( 'aria-expanded', 'false' ); } ); }); </script> <script> document.addEventListener('DOMContentLoaded', function () { document.querySelectorAll('.duplicate-lounge-check').forEach(function (checkbox) { checkbox.addEventListener('change', function () { var loungeId = this.id.replace('duplicate_lounge_', ''); var priceInput = document.querySelector( 'input[name="addquote[salas][' + loungeId + '][price]"]' ); if (!priceInput) { return; } priceInput.disabled = !this.checked; if (this.checked) { priceInput.focus(); } else { priceInput.value = ''; } }); }); /* * Cuando se abre/cierra un espacio cambiamos * visualmente la flecha. */ $('.duplicate-space-card .collapse').on('show.bs.collapse', function () { var button = $(this).prev('.duplicate-space-header'); button.attr('aria-expanded', 'true'); }); $('.duplicate-space-card .collapse').on('hide.bs.collapse', function () { var button = $(this).prev('.duplicate-space-header'); button.attr('aria-expanded', 'false'); }); }); </script> {# MODAL CONTRATOS FIRMADOS DEL EXPEDIENTE #} <div id="modal-reservation-signed-contracts" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="modalSignedContractsTitle" aria-hidden="true"> <div class="modal-dialog modal-lg"> <div class="modal-content" style="border-radius: 6px; overflow: hidden; box-shadow: 0 10px 30px rgba(0,0,0,0.2);"> <div class="modal-header" style="background-color: #101230; border-top: 4px solid #27ae60; color: #fff; padding: 14px 22px;"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true" style="color: #fff; opacity: 0.8; font-size: 24px;">×</button> <h4 class="modal-title" id="modalSignedContractsTitle" style="color: #fff; font-weight: bold; font-size: 16px;"> <i class="icon-file-check position-left" style="color: #27ae60;"></i> {% trans %}Contratos Firmados del Expediente{% endtrans %} </h4> </div> <div class="modal-body" style="padding: 20px; background: #f8fafc;"> <p class="text-muted" style="font-size: 12px; margin-bottom: 15px;"> <i class="icon-info22 position-left"></i> A continuación se listan todos los contratos formalizados digitalmente por el cliente para este expediente. El contrato marcado como <strong>VIGENTE</strong> es el vinculante actual. Los anteriores se conservan como histórico inmutable. </p> <div id="signed-contracts-table-container"> <div class="text-center text-muted" style="padding: 30px 0;"> <i class="glyphicon glyphicon-refresh glyphicon-refresh-animate"></i> Cargando contratos firmados... </div> </div> </div> <div class="modal-footer" style="padding: 12px 20px; background: #fff; border-top: 1px solid #e2e8f0;"> <button type="button" class="btn btn-default" data-dismiss="modal"> <i class="icon-cross2 position-left"></i> {% trans %}Cerrar{% endtrans %} </button> </div> </div> </div> </div> {# BARRA FIJA FLOTANTE INFERIOR: TOTAL GLOBAL DEL EXPEDIENTE #} <div class="navbar-fixed-bottom bg-vivid_sky_blue text-mint_cream" style="left: 280px; right: 0; padding: 12px 20px; box-shadow: 0 -2px 10px rgba(0,0,0,0.15); z-index: 99;"> <div class="container-fluid"> <div class="row text-center"> <div class="col-xs-4"> <span class="text-size-small text-uppercase" style="letter-spacing: 0.5px; opacity: 0.9;">{% trans %}VENTA TOTAL CLIENTE{% endtrans %}</span><br> <span class="text-bold" style="font-size: 20px; color: #ffffff;">{{ sumatoria_totales_global_con_iva|number_format(2, ',', '.') }} €</span> </div> <div class="col-xs-4"> <span class="text-size-small text-uppercase" style="letter-spacing: 0.5px; opacity: 0.9;">{% trans %}IVA{% endtrans %}</span><br> <span class="text-bold" style="font-size: 20px; color: #ffffff;">{{ sumatoria_totales_global_iva|number_format(2, ',', '.') }} €</span> </div> <div class="col-xs-4"> <span class="text-size-small text-uppercase" style="letter-spacing: 0.5px; opacity: 0.9;">{% trans %}VENTA SIN IVA{% endtrans %}</span><br> <span class="text-bold" style="font-size: 20px; color: #ffffff;">{{ sumatoria_totales_global_neto|number_format(2, ',', '.') }} €</span> </div> </div> </div></div>{% endblock %}