Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions events/migrations/0033_event_show_door_remaining.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('events', '0032_event_ingreso_anticipado_limite_carga'),
]

operations = [
migrations.AddField(
model_name='event',
name='show_door_remaining',
field=models.BooleanField(
default=False,
help_text='Si está marcado, en checkout sin entradas online se informa cuántas quedan en puerta.',
),
),
]
21 changes: 21 additions & 0 deletions events/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ class Event(BaseModel):
ingreso_anticipado_limite_carga = models.DateTimeField(blank=True, null=True, help_text="Fecha límite hasta la cual se pueden cargar o modificar ingresos anticipados. Si es null, no hay límite.")
show_multiple_tickets = models.BooleanField(default=False,
help_text="If unchecked, only the chepeast ticket will be shown.")
show_door_remaining = models.BooleanField(
default=False,
help_text="Si está marcado, en checkout sin entradas online se informa cuántas quedan en puerta.",
)

# homepage
header_image = models.ImageField(upload_to='events/heros', help_text=u"Dimensions: 1666px x 500px")
Expand Down Expand Up @@ -94,6 +98,23 @@ def tickets_remaining(self):
else:
return 999999999 # extra high number (easy hack)

def door_tickets_remaining(self):
"""Stock disponible en puerta (tipos con show_in_caja), acotado al cupo del evento."""
from tickets.models import TicketType

caja_stock = (
TicketType.objects.filter(
event=self,
show_in_caja=True,
is_direct_type=False,
ticket_count__gt=0,
).aggregate(total=Sum('ticket_count'))['total']
or 0
)
if self.max_tickets:
return min(caja_stock, max(0, self.tickets_remaining() or 0))
return caja_stock

def volunteer_period(self):
if self.end < timezone.now():
return False
Expand Down
6 changes: 6 additions & 0 deletions tickets/templates/checkout/select_tickets.html
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,12 @@ <h1 class="card-title">Bonos {{ event.name }}</h1>
id="continue-button"
disabled>Continuar</button>
</form>
{% elif show_door_remaining_notice %}
<div class="alert alert-info w-100" role="alert">
<p class="mb-0">
No quedan más entradas online{% if door_tickets_remaining > 0 %}, todavía quedan <strong>{{ door_tickets_remaining|intcomma }}</strong> disponibles en la puerta del evento{% else %}. Tampoco quedan más entradas en puerta{% endif %}.
</p>
</div>
{% else %}
<div class="alert alert-danger w-100" role="alert">
No hay tickets a la venta disponibles en este momento.
Expand Down
23 changes: 19 additions & 4 deletions tickets/views/checkout.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@
from tickets.models import TicketType, Order, OrderTicket


def _checkout_door_context(event, ticket_data):
if ticket_data or not event.show_door_remaining:
return {}
return {
'show_door_remaining_notice': True,
'door_tickets_remaining': event.door_tickets_remaining(),
}


@login_required
def select_tickets(request, event_slug=None):
# Get event from URL slug or request
Expand All @@ -39,13 +48,16 @@ def select_tickets(request, event_slug=None):
tickets_remaining = event.tickets_remaining() or 0
available_tickets = event.max_tickets_per_order
available_tickets = min(available_tickets, tickets_remaining)
return render(request, 'checkout/select_tickets.html', {
context = {
'form': form,
'ticket_data': form.ticket_data,
'available_tickets': available_tickets,
'tickets_remaining': tickets_remaining,
'current_event': event,
})
'event': event,
}
context.update(_checkout_door_context(event, form.ticket_data))
return render(request, 'checkout/select_tickets.html', context)

tickets_remaining = event.tickets_remaining() or 0
available_tickets = event.max_tickets_per_order
Expand All @@ -64,13 +76,16 @@ def select_tickets(request, event_slug=None):

form = CheckoutTicketSelectionForm(initial=initial_data, event=event)

return render(request, 'checkout/select_tickets.html', {
context = {
'form': form,
'ticket_data': form.ticket_data,
'available_tickets': available_tickets,
'tickets_remaining': tickets_remaining,
'current_event': event,
})
'event': event,
}
context.update(_checkout_door_context(event, form.ticket_data))
return render(request, 'checkout/select_tickets.html', context)


@login_required
Expand Down
20 changes: 19 additions & 1 deletion user_profile/templates/mi_fuego/ticket_types_management.html
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,15 @@ <h5 class="card-title mb-0">
<small class="field-help">Si está marcado, este tipo de entrada aparecerá en la interfaz de caja</small>
</div>
</div>
<div class="field-group">
<div class="form-check">
<input type="checkbox" class="form-check-input" id="do_not_show_in_checkout_{{ ticket_type.id }}" {% if ticket_type.do_not_show_in_checkout %}checked{% endif %} data-field="do_not_show_in_checkout" data-ticket-type-id="{{ ticket_type.id }}">
<label class="form-check-label field-label" for="do_not_show_in_checkout_{{ ticket_type.id }}">
Ocultar en checkout
</label>
<small class="field-help">Si está marcado, este tipo de entrada no aparecerá en el flujo de compra online</small>
</div>
</div>
</div>
</div>
</div>
Expand Down Expand Up @@ -208,7 +217,7 @@ <h5 class="modal-title" id="createTicketTypeModalLabel">
</div>

<div class="row">
<div class="col-md-12">
<div class="col-md-6">
<div class="form-check mb-3">
<input type="checkbox" class="form-check-input" id="show_in_caja_new" name="show_in_caja" checked>
<label class="form-check-label" for="show_in_caja_new">
Expand All @@ -217,6 +226,15 @@ <h5 class="modal-title" id="createTicketTypeModalLabel">
<small class="form-text text-muted d-block">Si está marcado, este tipo de entrada aparecerá en la interfaz de caja</small>
</div>
</div>
<div class="col-md-6">
<div class="form-check mb-3">
<input type="checkbox" class="form-check-input" id="do_not_show_in_checkout_new" name="do_not_show_in_checkout">
<label class="form-check-label" for="do_not_show_in_checkout_new">
Ocultar en checkout
</label>
<small class="form-text text-muted d-block">Si está marcado, este tipo de entrada no aparecerá en el flujo de compra online</small>
</div>
</div>
</div>
</div>
<div class="modal-footer">
Expand Down
7 changes: 4 additions & 3 deletions user_profile/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1993,8 +1993,8 @@ class TicketTypeForm(ModelForm):
class Meta:
model = TicketType
fields = [
'name', 'description', 'date_from', 'date_to',
'price', 'ticket_count', 'show_in_caja'
'name', 'description', 'date_from', 'date_to',
'price', 'ticket_count', 'show_in_caja', 'do_not_show_in_checkout',
]
widgets = {
'name': forms.TextInput(attrs={'class': 'form-control'}),
Expand All @@ -2004,6 +2004,7 @@ class Meta:
'price': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01', 'min': '0', 'placeholder': '0.00'}),
'ticket_count': forms.NumberInput(attrs={'class': 'form-control', 'min': '0'}),
'show_in_caja': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
'do_not_show_in_checkout': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
}

# Handle form submission
Expand Down Expand Up @@ -2145,7 +2146,7 @@ def ticket_types_ajax(request, event_slug):
setattr(ticket_type, field_name, parsed_date)
else:
setattr(ticket_type, field_name, None)
elif field_name == 'show_in_caja':
elif field_name in ['show_in_caja', 'do_not_show_in_checkout']:
setattr(ticket_type, field_name, value == 'true')

ticket_type.save()
Expand Down
Loading