diff --git a/caja/forms.py b/caja/forms.py index 241081f..e452410 100644 --- a/caja/forms.py +++ b/caja/forms.py @@ -10,10 +10,11 @@ class EventProductForm(ModelForm): class Meta: model = EventProduct - fields = ['name', 'price', 'is_active', 'ticket_type'] + fields = ['name', 'price', 'image', 'is_active', 'ticket_type'] widgets = { 'name': forms.TextInput(attrs={'class': 'form-control'}), 'price': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01', 'min': '0'}), + 'image': forms.ClearableFileInput(attrs={'class': 'form-control', 'accept': 'image/*'}), 'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}), 'ticket_type': forms.Select(attrs={'class': 'form-select'}), } diff --git a/caja/migrations/0003_cajasale_cancellation_fields.py b/caja/migrations/0003_cajasale_cancellation_fields.py new file mode 100644 index 0000000..8390d66 --- /dev/null +++ b/caja/migrations/0003_cajasale_cancellation_fields.py @@ -0,0 +1,36 @@ +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ('caja', '0002_migrate_ticket_stock'), + ] + + operations = [ + migrations.AddField( + model_name='cajasale', + name='notes', + field=models.TextField(blank=True), + ), + migrations.AddField( + model_name='cajasale', + name='related_sale', + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name='cancellations', + to='caja.cajasale', + ), + ), + migrations.AddField( + model_name='cajasale', + name='sale_type', + field=models.CharField( + choices=[('SALE', 'Venta'), ('CANCELLATION', 'Cancelación')], + default='SALE', + max_length=20, + ), + ), + ] diff --git a/caja/migrations/0004_eventproduct_image.py b/caja/migrations/0004_eventproduct_image.py new file mode 100644 index 0000000..34ab1e9 --- /dev/null +++ b/caja/migrations/0004_eventproduct_image.py @@ -0,0 +1,15 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ('caja', '0003_cajasale_cancellation_fields'), + ] + + operations = [ + migrations.AddField( + model_name='eventproduct', + name='image', + field=models.ImageField(blank=True, null=True, upload_to='caja/products/'), + ), + ] diff --git a/caja/models.py b/caja/models.py index f476c27..f3a6464 100644 --- a/caja/models.py +++ b/caja/models.py @@ -20,6 +20,7 @@ class EventProduct(BaseModel): ) name = models.CharField(max_length=200, blank=True) price = models.DecimalField(decimal_places=2, max_digits=10, null=True, blank=True) + image = models.ImageField(upload_to='caja/products/', blank=True, null=True) is_active = models.BooleanField(default=True) class Meta: @@ -189,11 +190,28 @@ class Status(models.TextChoices): CANCELLED = 'CANCELLED', 'Cancelada' EXPIRED = 'EXPIRED', 'Expirada' + class SaleType(models.TextChoices): + SALE = 'SALE', 'Venta' + CANCELLATION = 'CANCELLATION', 'Cancelación' + event_caja = models.ForeignKey(EventCaja, on_delete=models.CASCADE, related_name='sales') sold_by = models.ForeignKey(User, on_delete=models.RESTRICT, related_name='caja_sales') payment_method = models.CharField(max_length=20, choices=PaymentMethod.choices) + sale_type = models.CharField( + max_length=20, + choices=SaleType.choices, + default=SaleType.SALE, + ) status = models.CharField(max_length=20, choices=Status.choices, default=Status.PENDING) total_amount = models.DecimalField(decimal_places=2, max_digits=10, default=Decimal('0')) + notes = models.TextField(blank=True) + related_sale = models.ForeignKey( + 'self', + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name='cancellations', + ) customer_email = models.EmailField(blank=True) mark_as_used = models.BooleanField(default=False) order = models.ForeignKey( diff --git a/caja/urls.py b/caja/urls.py index 2bf1f97..639d2d9 100644 --- a/caja/urls.py +++ b/caja/urls.py @@ -2,6 +2,7 @@ from caja.views import ( api_cancel_sale, + api_cancel_paid_sale, api_create_sale, api_pay_mp_point, api_pay_mp_qr, @@ -10,6 +11,7 @@ caja_events_v2_view, caja_sales_report_view, caja_v2_operator_view, + caja_v2_summary_view, cajas_list_view, event_report_view, product_edit_view, @@ -57,6 +59,11 @@ caja_v2_operator_view, name='caja_v2_operator', ), + path( + 'mis-eventos//cajas-v2//resumen/', + caja_v2_summary_view, + name='caja_v2_summary', + ), path( 'mis-eventos//cajas-v2//api/sales/', api_create_sale, @@ -82,4 +89,9 @@ api_cancel_sale, name='caja_v2_api_cancel_sale', ), + path( + 'mis-eventos//cajas-v2//api/sales//cancel-paid/', + api_cancel_paid_sale, + name='caja_v2_api_cancel_paid_sale', + ), ] diff --git a/caja/views/__init__.py b/caja/views/__init__.py index 7ee6c8d..3f7b7f5 100644 --- a/caja/views/__init__.py +++ b/caja/views/__init__.py @@ -13,9 +13,11 @@ ) from caja.views.operator_views import ( api_cancel_sale, + api_cancel_paid_sale, api_create_sale, api_pay_mp_point, api_pay_mp_qr, api_sale_status, caja_v2_operator_view, + caja_v2_summary_view, ) diff --git a/caja/views/admin_views.py b/caja/views/admin_views.py index c003a4e..cf849ee 100644 --- a/caja/views/admin_views.py +++ b/caja/views/admin_views.py @@ -71,34 +71,12 @@ def product_edit_view(request, event_slug, product_id): event = get_event_for_admin(request.user, event_slug) product = get_object_or_404(EventProduct, id=product_id, event=event) stock = ensure_stock_row(product) - records = EventProductStockRecord.objects.filter(event_product=product)[:20] is_unlimited = stock.quantity is None if request.method == 'POST': - action = request.POST.get('action', 'save') - - if action in ('add_stock', 'remove_stock'): - stock.refresh_from_db() - if stock.quantity is None: - messages.error(request, 'No podés ajustar stock mientras el producto es ilimitado.') - return redirect('caja_product_edit', event_slug=event.slug, product_id=product.id) - - stock_form = StockQuantityForm(request.POST) - if stock_form.is_valid(): - qty = stock_form.cleaned_data['quantity'] - delta = qty if action == 'add_stock' else -qty - notes = stock_form.cleaned_data.get('notes', '') - adjust_stock(product, delta, request.user, notes=notes) - verb = 'agregado' if action == 'add_stock' else 'quitado' - messages.success(request, f'Stock {verb}: {qty} unidad(es).') - else: - for field, errors in stock_form.errors.items(): - for error in errors: - messages.error(request, f'{field}: {error}') - return redirect('caja_product_edit', event_slug=event.slug, product_id=product.id) - form = EventProductEditForm( request.POST, + request.FILES, instance=product, event=event, stock_unlimited=is_unlimited, @@ -119,10 +97,6 @@ def product_edit_view(request, event_slug, product_id): context.update({ 'product': product, 'form': form, - 'stock': stock, - 'stock_form': StockQuantityForm(), - 'records': records, - 'available': available(product), 'is_unlimited': is_unlimited, }) return render(request, 'mi_fuego/caja_v2/product_edit.html', context) @@ -130,7 +104,48 @@ def product_edit_view(request, event_slug, product_id): @login_required def product_stock_view(request, event_slug, product_id): - return redirect('caja_product_edit', event_slug=event_slug, product_id=product_id) + event = get_event_for_admin(request.user, event_slug) + product = get_object_or_404(EventProduct, id=product_id, event=event) + stock = ensure_stock_row(product) + records = EventProductStockRecord.objects.filter(event_product=product)[:20] + is_unlimited = stock.quantity is None + + if request.method == 'POST': + action = request.POST.get('action') + if action not in ('add_stock', 'remove_stock'): + raise Http404('Acción inválida') + + stock.refresh_from_db() + if stock.quantity is None: + messages.error(request, 'No podés ajustar stock mientras el producto es ilimitado.') + return redirect('caja_product_stock', event_slug=event.slug, product_id=product.id) + + stock_form = StockQuantityForm(request.POST) + if stock_form.is_valid(): + qty = stock_form.cleaned_data['quantity'] + delta = qty if action == 'add_stock' else -qty + notes = stock_form.cleaned_data.get('notes', '') + adjust_stock(product, delta, request.user, notes=notes) + verb = 'agregado' if action == 'add_stock' else 'quitado' + messages.success(request, f'Stock {verb}: {qty} unidad(es).') + return redirect('caja_product_stock', event_slug=event.slug, product_id=product.id) + + for field, errors in stock_form.errors.items(): + for error in errors: + messages.error(request, f'{field}: {error}') + else: + stock_form = StockQuantityForm() + + context = mi_fuego_admin_context(request, event, f'caja_products_{event.slug}') + context.update({ + 'product': product, + 'stock': stock, + 'stock_form': stock_form, + 'records': records, + 'available': available(product), + 'is_unlimited': is_unlimited, + }) + return render(request, 'mi_fuego/caja_v2/product_stock.html', context) @login_required diff --git a/caja/views/operator_views.py b/caja/views/operator_views.py index ec2ef0d..252cf44 100644 --- a/caja/views/operator_views.py +++ b/caja/views/operator_views.py @@ -1,12 +1,10 @@ import json import logging -import uuid -from django.contrib import messages from django.contrib.auth.decorators import login_required -from django.db import models +from django.db import models, transaction from django.http import JsonResponse -from django.shortcuts import get_object_or_404, redirect, render +from django.shortcuts import get_object_or_404, render from django.views.decorators.http import require_GET, require_POST from caja.context import mi_fuego_admin_context @@ -26,7 +24,6 @@ from caja.services.mercadopago_setup import ensure_mp_qr_config from caja.services.sales import create_pending_sale, finalize_caja_sale from caja.stock import available, InsufficientStockError -from events.models import Event logger = logging.getLogger(__name__) @@ -38,6 +35,40 @@ def _caja_products_for_sale(caja): ).select_related('event_product', 'event_product__ticket_type', 'event_product__stock') +def _caja_payment_totals(caja): + paid_sales = CajaSale.objects.filter( + event_caja=caja, + status=CajaSale.Status.PAID, + ) + totals = paid_sales.aggregate( + cash_total=models.Sum( + 'total_amount', + filter=models.Q( + payment_method__in=[ + CajaSale.PaymentMethod.EFECTIVO, + CajaSale.PaymentMethod.TRANSFERENCIA, + ], + ), + default=0, + ), + mp_total=models.Sum( + 'total_amount', + filter=models.Q( + payment_method__in=[ + CajaSale.PaymentMethod.MP_QR, + CajaSale.PaymentMethod.MP_POINT, + ], + ), + default=0, + ), + ) + return { + 'cash_total': totals['cash_total'] or 0, + 'mp_total': totals['mp_total'] or 0, + 'tx_count': paid_sales.count(), + } + + @login_required def caja_v2_operator_view(request, event_slug, caja_id): event = get_event_for_caja(request.user, event_slug) @@ -72,12 +103,35 @@ def caja_v2_operator_view(request, event_slug, caja_id): 'has_ticket_products': has_ticket_products, 'mp_qr_ready': mp_config.qr_ready if mp_config else False, 'mp_point_ready': mp_config.point_ready if mp_config else False, + 'caja_payment_totals': _caja_payment_totals(caja), }) if has_ticket_products: context['stats'] = ticket_caja_operator_stats(event) return render(request, 'mi_fuego/caja_v2/operator.html', context) +@login_required +def caja_v2_summary_view(request, event_slug, caja_id): + event = get_event_for_caja(request.user, event_slug) + caja = get_object_or_404(EventCaja, id=caja_id, event=event, is_active=True) + sales = ( + CajaSale.objects.filter( + event_caja=caja, + ) + .exclude(status=CajaSale.Status.PENDING) + .select_related('sold_by', 'related_sale') + .prefetch_related('lines__event_product', 'cancellations') + .order_by('-created_at') + ) + context = mi_fuego_admin_context(request, event, f'caja_v2_{event.slug}_{caja.id}') + context.update({ + 'caja': caja, + 'sales': sales, + 'caja_payment_totals': _caja_payment_totals(caja), + }) + return render(request, 'mi_fuego/caja_v2/caja_summary.html', context) + + @login_required @require_POST def api_create_sale(request, event_slug, caja_id): @@ -278,3 +332,50 @@ def api_cancel_sale(request, event_slug, caja_id, sale_id): sale.status = CajaSale.Status.CANCELLED sale.save(update_fields=['status', 'updated_at']) return JsonResponse({'sale_id': sale.id, 'status': sale.status}) + + +@login_required +@require_POST +def api_cancel_paid_sale(request, event_slug, caja_id, sale_id): + event = get_event_for_caja(request.user, event_slug) + caja = get_object_or_404(EventCaja, id=caja_id, event=event) + sale = get_object_or_404( + CajaSale, + id=sale_id, + event_caja=caja, + status=CajaSale.Status.PAID, + sale_type=CajaSale.SaleType.SALE, + ) + + try: + data = json.loads(request.body) + except json.JSONDecodeError: + return JsonResponse({'error': 'JSON inválido'}, status=400) + + reason = (data.get('reason') or '').strip() + if not reason: + return JsonResponse({'error': 'Debe indicar un motivo'}, status=400) + + with transaction.atomic(): + sale = CajaSale.objects.select_for_update().get(pk=sale.pk) + if sale.cancellations.exists(): + return JsonResponse({'error': 'La transacción ya fue cancelada'}, status=400) + + cancellation = CajaSale.objects.create( + event_caja=sale.event_caja, + sold_by=request.user, + payment_method=sale.payment_method, + sale_type=CajaSale.SaleType.CANCELLATION, + status=CajaSale.Status.PAID, + total_amount=-sale.total_amount, + customer_email=sale.customer_email, + related_sale=sale, + notes=f'Cancelación de tx #{sale.id}. Motivo: {reason}', + mark_as_used=False, + ) + + return JsonResponse({ + 'sale_id': sale.id, + 'cancellation_id': cancellation.id, + 'status': 'ok', + }) diff --git a/tickets/static/css/barbu-style.css b/tickets/static/css/barbu-style.css index 32c182a..8187c17 100644 --- a/tickets/static/css/barbu-style.css +++ b/tickets/static/css/barbu-style.css @@ -525,9 +525,13 @@ dl { .badge { width: fit-content; - color: #289e6d !important; - background-color: #e9f5f0; padding: 0.5rem; + color: #fff !important; +} + +.badge.text-dark, +.badge.text-black { + color: #212529 !important; } .rainbow-border { diff --git a/tickets/templates/tickets/barbu_base.html b/tickets/templates/tickets/barbu_base.html index ff2f05b..5365d40 100644 --- a/tickets/templates/tickets/barbu_base.html +++ b/tickets/templates/tickets/barbu_base.html @@ -26,13 +26,12 @@ {% endblock title %} Fuego Austral – La experiencia será lo que hagamos de ella {% block extrahead %}{% endblock %} - {% if user.is_authenticated and user.profile.profile_completion == 'COMPLETE' and not request.resolver_match.url_name == 'scan_tickets' and not request.resolver_match.url_name == 'scan_tickets_event' %} + {% if user.is_authenticated and user.profile.profile_completion == 'COMPLETE' and not request.resolver_match.url_name == 'scan_tickets' and not request.resolver_match.url_name == 'scan_tickets_event' and not request.resolver_match.url_name == 'caja' and not request.resolver_match.url_name == 'caja_v2_operator' %} +{% endblock %} diff --git a/user_profile/templates/mi_fuego/caja_v2/operator.html b/user_profile/templates/mi_fuego/caja_v2/operator.html index 2961890..903606e 100644 --- a/user_profile/templates/mi_fuego/caja_v2/operator.html +++ b/user_profile/templates/mi_fuego/caja_v2/operator.html @@ -21,6 +21,19 @@

{{ ca #cart-section.caja-processing .form-check-input { pointer-events: none; } + @media (max-width: 767.98px) { + footer.container-xxl { + display: none !important; + } + } + .caja-product-thumb { + width: 40px; + height: 40px; + object-fit: cover; + border-radius: 0.375rem; + border: 1px solid #dee2e6; + flex-shrink: 0; + }
@@ -28,10 +41,15 @@

{{ ca {% for item in products %}
-
- {{ item.product.display_name }} -
- {% if item.unlimited %}Ilimitado{% else %}Stock: {{ item.available }}{% endif %} +
+ {% if item.product.image %} + {{ item.product.display_name }} + {% endif %} +
+ {{ item.product.display_name }} +
+ {% if item.unlimited %}Ilimitado{% else %}Stock: {{ item.available }}{% endif %} +
@@ -64,19 +82,10 @@

{{ ca

{% endif %} -
Total: $0
- - +
Total: $0
- + {% if mp_qr_ready %}{% endif %} {% if mp_point_ready %}{% endif %}
@@ -128,10 +137,8 @@

¡Listo!

let cancelUrl = null; let activePayBtn = null; const payButtons = document.querySelectorAll('#pay-buttons [data-pay]'); - const cashMethodPicker = document.getElementById('cash-method-picker'); - const payButtonsRow = document.getElementById('pay-buttons'); const PAY_LABELS = { - CASH: 'Efectivo / Transferencia', + CASH: 'Efectivo', EFECTIVO: 'Efectivo', TRANSFERENCIA: 'Transferencia', MP_QR: 'QR', @@ -146,11 +153,6 @@

¡Listo!

return btn.dataset.payLabel || PAY_LABELS[btn.dataset.pay] || btn.dataset.pay; } - function showCashMethodPicker(show) { - cashMethodPicker.style.display = show ? 'block' : 'none'; - payButtonsRow.style.display = show ? 'none' : ''; - } - function getLines() { const lines = []; document.querySelectorAll('.qty-input').forEach(input => { @@ -250,7 +252,6 @@

¡Listo!

cancelUrl = null; setPayProcessing(false); resetMpQrUi(); - showCashMethodPicker(false); document.getElementById('point-section').style.display = 'none'; document.getElementById('success-section').style.display = 'none'; document.getElementById('caja-header').style.display = ''; @@ -364,24 +365,12 @@

¡Listo!

document.getElementById('mp-qr-cancel').addEventListener('click', cancelPendingSale); document.getElementById('point-cancel').addEventListener('click', cancelPendingSale); - document.querySelector('[data-cash-pick-cancel]').addEventListener('click', () => { - showCashMethodPicker(false); - }); - - document.querySelectorAll('[data-cash-pick]').forEach((btn) => { - btn.addEventListener('click', () => { - const cashBtn = document.querySelector('[data-pay="CASH"]'); - processSale(btn.dataset.cashPick, cashBtn); - }); - }); - async function processSale(paymentMethod, btn) { const lines = getLines(); if (!lines.length) { alert('Seleccioná al menos un producto'); return; } - showCashMethodPicker(false); setPayProcessing(true, btn); try { const sale = await postJson(createUrl, { @@ -437,7 +426,7 @@

¡Listo!

return; } if (btn.dataset.pay === 'CASH') { - showCashMethodPicker(true); + await processSale('EFECTIVO', btn); return; } await processSale(btn.dataset.pay, btn); diff --git a/user_profile/templates/mi_fuego/caja_v2/product_edit.html b/user_profile/templates/mi_fuego/caja_v2/product_edit.html index 8562e45..b1160db 100644 --- a/user_profile/templates/mi_fuego/caja_v2/product_edit.html +++ b/user_profile/templates/mi_fuego/caja_v2/product_edit.html @@ -10,13 +10,22 @@

Editar producto: {{ product.display_name }}

{% endfor %} {% endif %} -
+ {% csrf_token %}
{{ form.ticket_type.label_tag }} {{ form.ticket_type }}
{{ form.name.label_tag }} {{ form.name }}
{{ form.price.label_tag }} {{ form.price }}
+
+ {{ form.image.label_tag }} + {{ form.image }} + {% if product.image %} +
+ Imagen del producto +
+ {% endif %} +
{{ form.is_active }} @@ -35,90 +44,9 @@

Editar producto: {{ product.display_name }}

{% endif %} - -
-
Ajustar stock
-
-
- {% csrf_token %} -
- {{ stock_form.quantity.label_tag }} - {{ stock_form.quantity }} -
-
- {{ stock_form.notes.label_tag }} - {{ stock_form.notes }} -
-
- -
-
- -
-
-
-
- -
- Cantidad actual: - - {% if is_unlimited %}Ilimitado{% else %}{{ available }} unidad{{ available|pluralize:"es" }}{% endif %} - -
- - {% if records %} -
Historial de stock
- - - - {% for r in records %} - - - - - - - - {% endfor %} - -
FechaDeltaSaldoMotivoNotas
{{ r.created_at|date:'d/m/Y H:i' }}{{ r.delta }}{% if r.balance_after is None %}∞{% else %}{{ r.balance_after }}{% endif %}{{ r.get_reason_display }}{{ r.notes }}
- {% endif %}
- - - {% endblock %} diff --git a/user_profile/templates/mi_fuego/caja_v2/product_stock.html b/user_profile/templates/mi_fuego/caja_v2/product_stock.html index 9c5cc0b..f46a8ca 100644 --- a/user_profile/templates/mi_fuego/caja_v2/product_stock.html +++ b/user_profile/templates/mi_fuego/caja_v2/product_stock.html @@ -2,37 +2,58 @@ {% block submenu %}{% include 'mi_fuego/partials/event_admin_menu.html' %}{% endblock %} {% block truecontent %}
-

Stock: {{ product.display_name }}

-

Disponible: {% if available is None %}Ilimitado{% else %}{{ available }}{% endif %}

+
+

Modificar stock: {{ product.display_name }}

+ +
+ {% if messages %} {% for message in messages %} -
{{ message }}
+
{{ message }}
{% endfor %} {% endif %} -
- {% csrf_token %} -
-
- {{ form.unlimited }} - -
-
-
- {{ form.delta.label_tag }} - {{ form.delta }} -
Sumá o restá unidades (ej. +10 o -5). Opcional al pasar de ilimitado a limitado.
+ +
+ Cantidad actual: + + {% if is_unlimited %}Ilimitado{% else %}{{ available }} unidad{{ available|pluralize:"es" }}{% endif %} + +
+ +
+
Ajustar stock
+
+ {% if is_unlimited %} +
+ Este producto está en modo ilimitado. Desactivá "Stock ilimitado" en editar producto para poder ajustarlo. +
+ {% else %} + + {% csrf_token %} +
+ {{ stock_form.quantity.label_tag }} + {{ stock_form.quantity }} +
+
+ {{ stock_form.notes.label_tag }} + {{ stock_form.notes }} +
+
+ +
+
+ +
+ + {% endif %}
-
- {{ form.notes.label_tag }} - {{ form.notes }} -
- {% if form.errors %} -
{{ form.errors }}
- {% endif %} - - Volver - -
Historial
+
+ + {% if records %} +
Historial de stock
@@ -47,20 +68,20 @@
Historial
{% endfor %}
FechaDeltaSaldoMotivoNotas
+ {% endif %}
- + + {% endblock %} diff --git a/user_profile/templates/mi_fuego/caja_v2/products_list.html b/user_profile/templates/mi_fuego/caja_v2/products_list.html index 47cb21b..085a1ff 100644 --- a/user_profile/templates/mi_fuego/caja_v2/products_list.html +++ b/user_profile/templates/mi_fuego/caja_v2/products_list.html @@ -21,6 +21,13 @@ color: #212529 !important; border: none !important; } +.caja-v2-products .product-thumb { + width: 36px; + height: 36px; + object-fit: cover; + border-radius: 0.375rem; + border: 1px solid #dee2e6; +}
@@ -96,20 +103,27 @@

Productos — {{ event.name }} - {{ product.display_name }} - {% if product.ticket_type %} - Bono - {% else %} - Genérico - {% endif %} - {% if not product.is_active %} - Inactivo - {% endif %} +
+ {% if product.image %} + {{ product.display_name }} + {% endif %} +
+ {{ product.display_name }} + {% if product.ticket_type %} + Bono + {% else %} + Genérico + {% endif %} + {% if not product.is_active %} + Inactivo + {% endif %} +
+
${{ product.price|floatformat:0 }} {% if product.stock.quantity is None %}Ilimitado{% else %}{{ product.stock.quantity }}{% endif %} - Editar + Modificar {% empty %} diff --git a/user_profile/templates/mi_fuego/caja_v2/stock_report.html b/user_profile/templates/mi_fuego/caja_v2/stock_report.html index 27f402f..d7c13f2 100644 --- a/user_profile/templates/mi_fuego/caja_v2/stock_report.html +++ b/user_profile/templates/mi_fuego/caja_v2/stock_report.html @@ -68,7 +68,7 @@

Reporte de stocks — {{ e {% if row.is_active %}Activo{% else %}Inactivo{% endif %} - Editar + Modificar {% empty %} diff --git a/user_profile/templates/mi_fuego/caja_v2/ticket_stats_panel.html b/user_profile/templates/mi_fuego/caja_v2/ticket_stats_panel.html index 8ea3be7..18fe211 100644 --- a/user_profile/templates/mi_fuego/caja_v2/ticket_stats_panel.html +++ b/user_profile/templates/mi_fuego/caja_v2/ticket_stats_panel.html @@ -1,12 +1,18 @@ -{% if stats.caja_total_orders > 0 %} +{% load humanize %}