refactor: remoção do htmx do excluir item da comanda | feedback da exclusão

This commit is contained in:
2025-07-01 12:28:47 -03:00
parent 377fac4f1c
commit fe00c4da90
10 changed files with 151 additions and 189 deletions

View File

@@ -53,12 +53,22 @@ def removeProductComanda(request, productComanda_id):
'id':order.id, 'id':order.id,
'speak': f'Pedido cancelado! {order.id_product.name}.' 'speak': f'Pedido cancelado! {order.id_product.name}.'
}) })
asyncio.run(enviar_mensagem(msg)) # asyncio.run(enviar_mensagem(msg))
# order.delete() # order.delete()
consumo = ProductComanda.objects.filter(comanda=comanda)
valores = somar(consumo,comanda)
else: else:
product_comanda.delete() product_comanda.delete()
consumo = ProductComanda.objects.filter(comanda=comanda)
valores = somar(consumo,comanda)
return render(request, "htmx_components/comandas/htmx_list_products_in_comanda.html",{'config':config, 'valores': valores,'parcials':parcial,'consumo': consumo, 'comanda':comanda}) return render(request,
"htmx_components/comandas/htmx_list_products_in_comanda.html",
{'config':config,
'valores': valores,
'parcials':parcial,
'consumo': consumo,
'comanda':comanda})
else: else:
pass pass

View File

@@ -103,7 +103,7 @@ Detalhes {{comanda.name}}
{% for item in consumo%} {% for item in consumo%}
<tr> <tr id="item-{{item.id}}">
<td id="id-for-print-{{item.id}}"> <td id="id-for-print-{{item.id}}">
<spam style="cursor: pointer;" onclick="inforOrders({{item.id}})"> <spam style="cursor: pointer;" onclick="inforOrders({{item.id}})">
{{item.product.name}}</spam> {{item.product.name}}</spam>
@@ -131,13 +131,12 @@ Detalhes {{comanda.name}}
{% if comanda.status != 'OPEN'%} {% if comanda.status != 'OPEN'%}
{% else %} {% else %}
<td> <td>
<img <img
src="{% static 'midia/icons/delete.svg' %}" src="{% static 'midia/icons/delete.svg' %}"
style="width: 35px; height: 35px; cursor: pointer;" style="width: 35px; height: 35px; cursor: pointer;"
hx-get="{% url 'removeProductComanda' item.id %} " >
hx-trigger="click"
hx-target="#list-products-comanda"
hx-confirm="Tem certeza que deseja excluir o produto {{item.product.name}}?" >
</img> </img>
</td> </td>
{% endif %} {% endif %}
@@ -181,29 +180,20 @@ Detalhes {{comanda.name}}
</div> </div>
<div hidden id="addProduct" >
<div id="addProduct" class="popover">
<!-- <div id="productForm" > -->
{% csrf_token %} {% csrf_token %}
<input type="text" oninput="searchProduct()" id="search-product" name="search-product" placeholder="Buscar Produto" ><br> <input type="text" oninput="searchProduct()" id="search-product" name="search-product" placeholder="Buscar Produto" ><br>
<div id="product-list" class="grid-list-products"> <div id="product-list" class="grid-list-products">
{% for product in products %} {% for product in products %}
<div class="card-product" onclick="addProductComanda({{product.id}}, {{comanda.id}}, '{{product.cuisine}}')" > <div class="card-product" onclick="addProductComanda({{product.id}}, {{comanda.id}}, '{{product.cuisine}}')" >
{{product.name}} <br> {{product.name}} <br>
R$ {{product.price}} R$ {{product.price}}
</div > </div >
{% endfor %} {% endfor %}
</div> </div>
<!-- </div> -->
</div> </div>
<dialog id="payment-comanda" style="display: none;" > <dialog id="payment-comanda" style="display: none;" >
<article> <article>
<form action="{% url 'paymentComanda' comanda.id %}" method="post"> <form action="{% url 'paymentComanda' comanda.id %}" method="post">

View File

@@ -22,7 +22,7 @@ urlpatterns = [
htmx_urlpatterns = [ htmx_urlpatterns = [
path('removeProductComanda<int:productComanda_id>/', htmx_views.removeProductComanda, name='removeProductComanda'), path('removeProductComanda/<int:productComanda_id>/', htmx_views.removeProductComanda, name='removeProductComanda'),
path('reopenComanda<int:comanda_id>/', htmx_views.reopenComanda, name='reopenComanda'), path('reopenComanda<int:comanda_id>/', htmx_views.reopenComanda, name='reopenComanda'),
path('paymentComanda<int:comanda_id>/', htmx_views.paymentComanda, name='paymentComanda'), path('paymentComanda<int:comanda_id>/', htmx_views.paymentComanda, name='paymentComanda'),
path('paymentParcial<int:comanda_id>/', htmx_views.paymentParcial, name='paymentParcial'), path('paymentParcial<int:comanda_id>/', htmx_views.paymentParcial, name='paymentParcial'),

Binary file not shown.

View File

@@ -2,53 +2,51 @@
{% load custom_filter_tag %} {% load custom_filter_tag %}
<tr> <tr>
<th style="text-align: left;"><b>Produto</b></th> <th style="text-align: left;"><b>Produto</b></th>
<th style="text-align: left;"><b>Preço</b></th> <th style="text-align: left;"><b>Preço</b></th>
</tr> </tr>
{% for item in consumo%} {% for item in consumo%}
<tr> <tr id="item-{{item.id}}">
<td id="id-for-print-{{item.id}}"> <td id="id-for-print-{{item.id}}">
<spam style="cursor: pointer;" onclick="inforOrders({{item.id}})"> <spam style="cursor: pointer;" onclick="inforOrders({{item.id}})">
{{item.product.name}}</spam> {{item.product.name}}</spam>
{% if item.product.cuisine == True %} {% if item.product.cuisine == True %}
<input hidden id="{{item.id}}-obsOrder" type="order" value="{{item.id | obsOrder}}"> <input hidden id="{{item.id}}-obsOrder" type="order" value="{{item.id | obsOrder}}">
<img <img
onclick="openModalObs({{item.id}})" onclick="openModalObs({{item.id}})"
src="{% static 'midia/icons/note.svg' %}" src="{% static 'midia/icons/note.svg' %}"
style="width: 25px; height: 35px; cursor: pointer;"> style="width: 25px; height: 35px; cursor: pointer;">
</img> </img>
<img
onclick="printOrder({{item.id}})" <img
src="{% static 'midia/icons/print.svg' %}" onclick="printOrder({{item.id}})"
style="width: 35px; height: 35px; cursor: pointer;"> src="{% static 'midia/icons/print.svg' %}"
</img> style="width: 35px; height: 35px; cursor: pointer;">
</img>
{% endif %} {% endif %}
</td> </td>
<td>R$ {{item.product.price}}</td> <td>R$ {{item.product.price}}</td>
{% if comanda.status != 'OPEN'%}
{% else %}
<td>
{% if comanda.status != 'OPEN'%}
{% else %}
<td>
<img <img
onclick="removeProductComanda({{item.id}}, '{{item.product.name}}')"
src="{% static 'midia/icons/delete.svg' %}" src="{% static 'midia/icons/delete.svg' %}"
style="width: 35px; height: 35px; cursor: pointer;" style="width: 35px; height: 35px; cursor: pointer;"
hx-get="{% url 'removeProductComanda' item.id %} " >
hx-trigger="click" </img>
hx-target="#list-products-comanda" </td>
hx-confirm="Tem certeza que deseja excluir o produto {{item.product.name}}?" >
</img>
</td>
{% endif %} {% endif %}
</tr> </tr>
{% endfor %} {% endfor %}
{% if config.taxa %} {% if config.taxa %}
<tr> <tr>
@@ -74,7 +72,7 @@ style="width: 35px; height: 35px; cursor: pointer;">
<tfoot> <tfoot>
<tr> <tr>
{% if config.taxa %} {% if config.taxa %}
<td colspan="2" style="text-align: center;"><b>Total R$ {{valores.totalComTaxa}}</b></td> <td colspan="2" style="text-align: center;"><b>Total R$ {{valores.totalComTaxa}}</b></td>
@@ -82,5 +80,5 @@ style="width: 35px; height: 35px; cursor: pointer;">
<td colspan="2" style="text-align: center;"><b>Total R$ {{valores.totalSemTaxa}}</b></td> <td colspan="2" style="text-align: center;"><b>Total R$ {{valores.totalSemTaxa}}</b></td>
{% endif %} {% endif %}
</tr> </tr>
</tfoot> </tfoot>

View File

@@ -32,8 +32,7 @@
--pico-nav-link-spacing-vertical: 0.5rem; --pico-nav-link-spacing-vertical: 0.5rem;
--pico-nav-link-spacing-horizontal: 0.5rem; --pico-nav-link-spacing-horizontal: 0.5rem;
--pico-nav-breadcrumb-divider: ">"; --pico-nav-breadcrumb-divider: ">";
--pico-icon-checkbox: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(255, 255, 255)' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); --pico-icon-minus: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 24 24' fill='none' stroke='rgb(255, 255, 255)' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'%3E%3C/line%3E%3C/svg%3E");
--pico-icon-minus: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(255, 255, 255)' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'%3E%3C/line%3E%3C/svg%3E");
--pico-icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); --pico-icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
--pico-icon-date: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E"); --pico-icon-date: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E");
--pico-icon-time: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpolyline points='12 6 12 12 16 14'%3E%3C/polyline%3E%3C/svg%3E"); --pico-icon-time: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpolyline points='12 6 12 12 16 14'%3E%3C/polyline%3E%3C/svg%3E");
@@ -147,8 +146,8 @@ input, textarea, select {
.card-product { .card-product {
height: 180px; height: 130px;
width: 200px; width: 150px;
padding: 10px; padding: 10px;
align-items: center; align-items: center;
align-content: center; align-content: center;

View File

@@ -18,108 +18,14 @@
max-width: 800px; max-width: 800px;
} }
/* .card-product {
height: 180px;
width: 200px;
padding: 10px;
align-items: center;
align-content: center;
text-align: center;
line-height: 1.5;
background: var(--main-gradient);
box-shadow: 3px 3px 10px rgba(2, 2, 2, 0.678);
border-radius: 5px;
transition: transform 0.4s, box-shadow 0.4s;
}
.card-product:hover {
transform: scale(1.05);
transition: transform 0.4s, box-shadow 0.4s;
box-shadow: 0px 0px 10px rgba(86, 187, 255, 0.815);
} */
table td th { table td th {
text-align: center; text-align: center;
} }
.close {
height: 45px;
transition: transform 0.4s;
}
.close:hover {
transform: scale(1.2);
transition: transform 0.4s;
filter: drop-shadow(0px 0px 8px rgba(255, 1, 1, 0.452));
}
.popover{
display: none;
position: relative;
width: 98%;
height: 96%;
max-width: 800px;
top: 20px;
left: 25%;
padding: 20px;
background-color: #1f1f1fb6;
border-radius: 15px;
border: none;
box-shadow: 0px 0px 8px rgba(143, 143, 143, 0.2);
text-align: justify;
line-height: 50px;
font-size: 18px;
font-weight: bold;
z-index: 1;
/* color: #333; */
transition: transform 0.4s;
animation: jump 0.5s;
}
.popover::backdrop {
background-color: rgba(39, 39, 39, 0.315);
backdrop-filter: blur(5px);
}
.toast-add {
position: fixed;
width: 30%;
top: 40px;
left: 50%;
justify-items: center;
align-items: center;
transform: translateX(-50%);
background-color: #599100;
color: #000000;
font-weight: bold;
padding: 20px 1px 1px 1px;
border-radius: 10px;
opacity: 0;
visibility: hidden;
transition: opacity 0.5s ease-in-out, visibility 0.5s ease-in-out;
z-index: 200 !important;
}
.toast-add p {
color: #000000;
}
.toast-add.show {
opacity: 1;
visibility: visible;
}
@media screen and (max-width: 730px) { @media screen and (max-width: 730px) {
.toast-add {
width: 90%;
}
.popover{
width: 98%;
height: 98%;
max-width: 800px;
top: 20px;
left: 10px;
}
.card-product { .card-product {
height: 100%; height: 100%;

View File

@@ -9,6 +9,7 @@ const { value: formValues } = await Swal.fire({
title: "Adicionar Produto", title: "Adicionar Produto",
html: htmlModal, html: htmlModal,
width: '100em', width: '100em',
position:"top",
theme: "dark", theme: "dark",
didOpen: () => { didOpen: () => {
Swal.getPopup().classList.add('swal2-noautoclose'); Swal.getPopup().classList.add('swal2-noautoclose');
@@ -452,3 +453,61 @@ function inforOrders(id){
feedback(order[2], "", order[1]+' - '+order[5]); feedback(order[2], "", order[1]+' - '+order[5]);
} }
async function removeProductComanda(itemId, productName) {
var table = document.getElementById('list-products-comanda');
Swal.fire({
theme: "dark",
title: `Remover ${productName} da comanda?`,
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#d33",
cancelButtonColor: "#3085d6",
confirmButtonText: "Sim, remover!",
cancelButtonText: "Cancelar",
}).then(async (result) => {
if (result.isConfirmed) {
const csrfToken = document.querySelector('[name="csrfmiddlewaretoken"]').value
if (!csrfToken) {
throw new Error('Token de segurança não encontrado');
}
const response = await fetch(`/comandas/removeProductComanda/${itemId}/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrfToken
},
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
Swal.fire({
theme:"dark",
title: "😬 Ops!",
text: errorData.message || `Erro HTTP: ${response.status}`,
icon: "error"
});
throw new Error(errorData.message || `Erro HTTP: ${response.status}`);
}
const result = await response.text();
table.innerHTML = result;
Swal.fire({
theme:"dark",
title: "Feito!",
text: productName+" foi removido da comanda",
icon: "success"
});
}
});
}