mirror of
https://github.com/welton89/RRBEC.git
synced 2026-04-05 05:25:40 +00:00
refactor:alteração modal de add product na comanda
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -6,7 +6,7 @@ from django.shortcuts import render, redirect
|
||||
from comandas.models import Comanda, ProductComanda
|
||||
from orders.models import Order
|
||||
from products.models import Product
|
||||
from payments.models import Payments
|
||||
from payments.models import Payments, somar
|
||||
from typePay.models import TypePay
|
||||
from gestaoRaul.decorators import group_required
|
||||
from websocket_client.websocketClient import enviar_mensagem
|
||||
@@ -29,80 +29,6 @@ from asgiref.sync import async_to_sync
|
||||
# print(f"Erro ao enviar mensagem via websocket: {e}")
|
||||
|
||||
|
||||
def somar(consumo:ProductComanda, comanda:Comanda):
|
||||
parcial = Payments.objects.filter(comanda=comanda)
|
||||
totalParcial = Decimal(0)
|
||||
total:Decimal = Decimal(0)
|
||||
for p in parcial:
|
||||
totalParcial += p.value
|
||||
for produto in consumo:
|
||||
total += Decimal(produto.product.price)
|
||||
valores = {
|
||||
'total':total,
|
||||
'parcial':totalParcial,
|
||||
'taxa': round(total * Decimal(0.1), 2),
|
||||
'totalSemTaxa':total - totalParcial,
|
||||
'totalComTaxa': round((total - totalParcial)+(total * Decimal(0.1)),2)
|
||||
}
|
||||
return valores
|
||||
|
||||
def listProduct(request, comanda_id):
|
||||
product = request.GET.get("search-product")
|
||||
allProducts = Product.objects.filter(name__icontains=product)
|
||||
products = []
|
||||
for p in allProducts:
|
||||
if p.active == True:
|
||||
products.append(p)
|
||||
return render(request, "htmx_components/comandas/htmx_list_products.html", {"products": products,'comanda_id':comanda_id})
|
||||
|
||||
@group_required(groupName='Garçom')
|
||||
def addProduct(request, product_id, comanda_id):
|
||||
config = {
|
||||
'taxa': False
|
||||
}
|
||||
obs = request.GET.get("obs")
|
||||
product_comanda = ProductComanda(comanda_id=comanda_id, product_id=product_id)
|
||||
product_comanda.save()
|
||||
product = Product.objects.get(id=product_id)
|
||||
comanda = Comanda.objects.get(id=comanda_id)
|
||||
parcial = Payments.objects.filter(comanda=comanda)
|
||||
if product.cuisine == True:
|
||||
order = Order(id_comanda=comanda, id_product=product, productComanda=product_comanda, obs='')
|
||||
order.save()
|
||||
msg = JsonResponse({
|
||||
'type': 'broadcast',
|
||||
'message': f"""
|
||||
<div class="m-card" id="m-card-{order.id}">
|
||||
<h4>{product.name}</h4>
|
||||
<h4 id="obs-{order.id}"> {order.obs}</h4>
|
||||
<h4>{comanda.name} - {comanda.mesa.name}</h4>
|
||||
<h4> {order.queue.strftime("%d/%m/%Y - %H:%M")}</h4>
|
||||
<h4> Atendente: {comanda.user.first_name}</h4>
|
||||
<form method="path" action="/pedidos/preparing/{order.id}/">
|
||||
<button class="btn-primary" type="submit">Preparar</button>
|
||||
</form>
|
||||
</div>
|
||||
""",
|
||||
'local':'cozinha',
|
||||
'tipo':'add',
|
||||
'id':order.id,
|
||||
'speak': f'Novo pedido! {product.name}, para {comanda.name}.'
|
||||
})
|
||||
try:
|
||||
# Chama a função async dentro da view normal
|
||||
async_to_sync(enviar_mensagem)(mensagem)
|
||||
|
||||
# return JsonResponse({"status": "Mensagem enviada com sucesso"})
|
||||
|
||||
except Exception as e:
|
||||
print("Erro add product websocket: ",e)
|
||||
# return JsonResponse({"status": "Erro", "erro": str(e)}, status=500)
|
||||
# asyncio.run(enviar_mensagem(msg))
|
||||
consumo = ProductComanda.objects.filter(comanda=comanda_id)
|
||||
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})
|
||||
|
||||
|
||||
|
||||
@group_required(groupName='Garçom')
|
||||
|
||||
@@ -13,6 +13,16 @@ Detalhes {{comanda.name}}
|
||||
|
||||
{% block 'head' %}
|
||||
<link rel="stylesheet" href="{% static 'comandas/css/viewcomanda.css' %}">
|
||||
<style>
|
||||
.swal2-popup {
|
||||
position: relative; /* Necessário para o posicionamento absoluto do botão */
|
||||
}
|
||||
.posi {
|
||||
position: absolute !important;
|
||||
top: 0.5em;
|
||||
right: 0.5em;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
@@ -22,7 +32,7 @@ Detalhes {{comanda.name}}
|
||||
<input hidden id="id-temp" type="number">
|
||||
<div class="grid-container" >
|
||||
<div style="display: flex;padding: 5px;gap:8px">
|
||||
<button class="btn-primary" id="openModal" onclick="openModal()" popovertarget="addProduct"
|
||||
<button class="btn-primary" id="openModal" onclick="openModal()"
|
||||
{% if comanda.status != 'OPEN'%}
|
||||
disabled
|
||||
{% endif %}
|
||||
@@ -71,6 +81,7 @@ Detalhes {{comanda.name}}
|
||||
</div>
|
||||
<div>
|
||||
<input hidden type="text" id="h-mesaId" value="{{comanda.mesa.id}}">
|
||||
<input hidden type="text" id="id-comanda" value="{{comanda.id}}">
|
||||
<span id="name-comanda">Nome: {{comanda.name}} | </span>
|
||||
<span id="mesa-comanda">Local: {{comanda.mesa}}</span>
|
||||
|
||||
@@ -173,17 +184,13 @@ Detalhes {{comanda.name}}
|
||||
|
||||
|
||||
|
||||
<div id="addProduct" popover class="popover">
|
||||
<div id="toast-add" class="toast-add">
|
||||
<p id="toast-message-add"></p>
|
||||
</div>
|
||||
<form id="productForm" >
|
||||
<div style="display: flex;justify-content: space-between;">
|
||||
<h2>Adicionar Produto</h2> <img class="close" src="{% static 'midia/icons/close-circle.svg' %}" onclick="closeModal()">
|
||||
</div>
|
||||
<div id="addProduct" class="popover">
|
||||
<!-- <div id="productForm" > -->
|
||||
{% csrf_token %}
|
||||
|
||||
<input type="text" id="search-product" name="search-product" placeholder="Buscar Produto" hx-get="{% url 'listProduct' comanda.id %}" hx-trigger="keyup" hx-target="#product-list"><br>
|
||||
<input type="text" oninput="searchProduct()" id="search-product" name="search-product" placeholder="Buscar Produto" ><br>
|
||||
<div id="product-list" class="grid-list-products">
|
||||
|
||||
{% for product in products %}
|
||||
|
||||
<div class="card-product" onclick="addProductComanda({{product.id}}, {{comanda.id}}, '{{product.cuisine}}')" >
|
||||
@@ -192,7 +199,7 @@ Detalhes {{comanda.name}}
|
||||
</div >
|
||||
{% endfor %}
|
||||
</div>
|
||||
</form>
|
||||
<!-- </div> -->
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ urlpatterns = [
|
||||
path('notificacao/', views.notificacao, name='notificacao'),
|
||||
path('editOrders/<int:productComanda_id>/<str:obs>', views.editOrders, name='editOrders'),
|
||||
path('closeComanda/<int:comanda_id>/', views.closeComanda, name='closeComanda'),
|
||||
path('listProduct/<int:comanda_id>/<str:product>/', views.listProduct, name='listProduct'),
|
||||
path('product=<int:product_id>/comanda=<int:comanda_id>/', views.addProduct, name='addProduct'),
|
||||
|
||||
|
||||
|
||||
@@ -20,9 +22,6 @@ urlpatterns = [
|
||||
|
||||
|
||||
htmx_urlpatterns = [
|
||||
# path('listProduct/', htmx_views.listProduct, name='listProduct'),
|
||||
path('listProduct/<int:comanda_id>/', htmx_views.listProduct, name='listProduct'),
|
||||
path('addProduct<int:product_id>/<int:comanda_id>/', htmx_views.addProduct, name='addProduct'),
|
||||
path('removeProductComanda<int:productComanda_id>/', htmx_views.removeProductComanda, name='removeProductComanda'),
|
||||
path('reopenComanda<int:comanda_id>/', htmx_views.reopenComanda, name='reopenComanda'),
|
||||
path('paymentComanda<int:comanda_id>/', htmx_views.paymentComanda, name='paymentComanda'),
|
||||
|
||||
@@ -23,23 +23,6 @@ def comandas(request):
|
||||
return render(request, 'comandas.html', {'comandas': comandas, 'mesas': mesas})
|
||||
|
||||
|
||||
# def somar(consumo:ProductComanda, comanda:Comanda):
|
||||
# parcial = Payments.objects.filter(comanda=comanda)
|
||||
# totalParcial = Decimal(0)
|
||||
# total:Decimal = Decimal(0)
|
||||
# for p in parcial:
|
||||
# totalParcial += p.value
|
||||
# for produto in consumo:
|
||||
# total += Decimal(produto.product.price)
|
||||
# valores = {
|
||||
# 'total':total,
|
||||
# 'parcial':totalParcial,
|
||||
# 'taxa': round(total * Decimal(0.1), 2),
|
||||
# 'totalSemTaxa':total - totalParcial,
|
||||
# 'totalComTaxa': round((total - totalParcial)+(total * Decimal(0.1)),2)
|
||||
# }
|
||||
# return valores
|
||||
|
||||
@group_required(groupName='Garçom')
|
||||
def viewComanda(request):
|
||||
config = {
|
||||
@@ -167,3 +150,61 @@ def closeComanda(request, comanda_id):
|
||||
comanda.status = "PAYING"
|
||||
comanda.save()
|
||||
return JsonResponse({'status': 'ok', 'obs':'order.obs'})
|
||||
|
||||
@group_required(groupName='Garçom')
|
||||
def addProduct(request, product_id, comanda_id):
|
||||
config = {
|
||||
'taxa': False
|
||||
}
|
||||
obs = request.GET.get("obs")
|
||||
product_comanda = ProductComanda(comanda_id=comanda_id, product_id=product_id)
|
||||
product_comanda.save()
|
||||
product = Product.objects.get(id=product_id)
|
||||
comanda = Comanda.objects.get(id=comanda_id)
|
||||
parcial = Payments.objects.filter(comanda=comanda)
|
||||
if product.cuisine == True:
|
||||
order = Order(id_comanda=comanda, id_product=product, productComanda=product_comanda, obs='')
|
||||
order.save()
|
||||
msg = JsonResponse({
|
||||
'type': 'broadcast',
|
||||
'message': f"""
|
||||
<div class="m-card" id="m-card-{order.id}">
|
||||
<h4>{product.name}</h4>
|
||||
<h4 id="obs-{order.id}"> {order.obs}</h4>
|
||||
<h4>{comanda.name} - {comanda.mesa.name}</h4>
|
||||
<h4> {order.queue.strftime("%d/%m/%Y - %H:%M")}</h4>
|
||||
<h4> Atendente: {comanda.user.first_name}</h4>
|
||||
<form method="path" action="/pedidos/preparing/{order.id}/">
|
||||
<button class="btn-primary" type="submit">Preparar</button>
|
||||
</form>
|
||||
</div>
|
||||
""",
|
||||
'local':'cozinha',
|
||||
'tipo':'add',
|
||||
'id':order.id,
|
||||
'speak': f'Novo pedido! {product.name}, para {comanda.name}.'
|
||||
})
|
||||
try:
|
||||
# Chama a função async dentro da view normal
|
||||
async_to_sync(enviar_mensagem)(mensagem)
|
||||
|
||||
# return JsonResponse({"status": "Mensagem enviada com sucesso"})
|
||||
|
||||
except Exception as e:
|
||||
print("Erro add product websocket: ",e)
|
||||
# return JsonResponse({"status": "Erro", "erro": str(e)}, status=500)
|
||||
# asyncio.run(enviar_mensagem(msg))
|
||||
consumo = ProductComanda.objects.filter(comanda=comanda_id)
|
||||
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})
|
||||
|
||||
|
||||
|
||||
def listProduct(request, comanda_id, product):
|
||||
allProducts = Product.objects.filter(name__icontains=product)
|
||||
products = []
|
||||
for p in allProducts:
|
||||
if p.active == True:
|
||||
products.append(p)
|
||||
return render(request, "htmx_components/comandas/htmx_list_products.html", {"products": products,'comanda_id':comanda_id})
|
||||
Binary file not shown.
@@ -3,11 +3,9 @@
|
||||
{% for product in products %}
|
||||
|
||||
<div
|
||||
onclick="addProductComanda({{product.id}})"
|
||||
onclick="addProductComanda({{product.id}}, {{comanda_id}}, '{{product.cuisine}}')"
|
||||
class="card-product"
|
||||
hx-get="{% url 'addProduct' product.id comanda_id %} "
|
||||
hx-trigger="click"
|
||||
hx-target="#list-products-comanda">
|
||||
>
|
||||
{{product.name}} <br>
|
||||
R$ {{product.price}}
|
||||
</div>
|
||||
|
||||
@@ -178,7 +178,6 @@ function openFullscreen() {
|
||||
|
||||
|
||||
function feedback(message, icon, subMessage) {
|
||||
console.log(subMessage)
|
||||
var feedbackMsg = Swal.fire({
|
||||
color: 'white',
|
||||
title: message,
|
||||
@@ -189,5 +188,6 @@ function openFullscreen() {
|
||||
background: 'rgb(23, 38, 54)',
|
||||
confirmButtonColor: 'linear-gradient(145deg, #1E2A3B, #2C3E50)',
|
||||
});
|
||||
return feedbackMsg;
|
||||
|
||||
|
||||
}
|
||||
@@ -53,6 +53,7 @@
|
||||
}
|
||||
|
||||
.popover{
|
||||
display: none;
|
||||
position: relative;
|
||||
width: 98%;
|
||||
height: 96%;
|
||||
|
||||
@@ -1,23 +1,52 @@
|
||||
|
||||
|
||||
async function openModal() {
|
||||
var htmlModal = document.getElementById('addProduct').innerHTML
|
||||
htmlModal = htmlModal.replace('search-product','search-product-modal')
|
||||
htmlModal = htmlModal.replace('product-list','product-list-modal')
|
||||
|
||||
const { value: formValues } = await Swal.fire({
|
||||
title: "Adicionar Produto",
|
||||
html: htmlModal,
|
||||
width: '100em',
|
||||
theme: "dark",
|
||||
didOpen: () => {
|
||||
Swal.getPopup().classList.add('swal2-noautoclose');
|
||||
},
|
||||
showConfirmButton: false,
|
||||
showCancelButton: true,
|
||||
cancelButtonText: '×',
|
||||
customClass:{
|
||||
cancelButton:'posi'
|
||||
},
|
||||
focusConfirm: false,
|
||||
});
|
||||
|
||||
|
||||
|
||||
function openModal() {
|
||||
textField = document.getElementById('search-product')
|
||||
if (textField) {
|
||||
}
|
||||
|
||||
function searchProduct() {
|
||||
setTimeout(() => {
|
||||
textField.focus();
|
||||
}, 500);
|
||||
}
|
||||
textField.value = '';
|
||||
}
|
||||
time();
|
||||
}, 100);
|
||||
function time(){
|
||||
var search_product = document.getElementById('search-product-modal').value.trim()
|
||||
var productListElement = document.getElementById("product-list-modal");
|
||||
var comanda_id = document.getElementById("id-comanda").value;
|
||||
|
||||
if(search_product.length == 0 ){search_product ='*';}
|
||||
fetch(`/comandas/listProduct/${comanda_id}/${search_product}`, {
|
||||
method: 'GET',}
|
||||
).then(function(response) {
|
||||
return response.text();
|
||||
}).then(function(text) {
|
||||
productListElement.innerHTML = text;
|
||||
|
||||
|
||||
function closeModal() {
|
||||
var popover = document.getElementById('addProduct');
|
||||
popover.hidePopover()
|
||||
})}
|
||||
}
|
||||
|
||||
|
||||
function openModalAlter() {
|
||||
document.getElementById('Modal-alter-comanda').style.display = 'block';
|
||||
var name = document.getElementById('name-comanda').innerText.replace('Nome: ','').replace(' | ', '')
|
||||
@@ -328,43 +357,80 @@ function addOrder(id, obs){
|
||||
}
|
||||
|
||||
|
||||
function showToastAdd(message, type ,duration = 3000) {
|
||||
const toast = document.getElementById('toast-add');
|
||||
|
||||
if (type === 'success') {
|
||||
toast.style.backgroundColor = '#28a745';
|
||||
} else if (type === 'error') {
|
||||
toast.style.backgroundColor = '#dc3545';
|
||||
} else if (type === 'info') {
|
||||
toast.style.backgroundColor = '#ffc107';
|
||||
async function addProductComanda(productId, comandaId, cuisine) {
|
||||
try {
|
||||
if (!productId || !comandaId) {
|
||||
throw new Error('IDs de produto ou comanda inválidos');
|
||||
}
|
||||
const toastMessage = document.getElementById('toast-message-add');
|
||||
toastMessage.textContent = message;
|
||||
toast.classList.add('show');
|
||||
|
||||
setTimeout(() => {
|
||||
toast.classList.remove('show');
|
||||
}, duration);
|
||||
const csrfToken = document.querySelector('[name="csrfmiddlewaretoken"]').value
|
||||
if (!csrfToken) {
|
||||
throw new Error('Token de segurança não encontrado');
|
||||
}
|
||||
function addProductComanda(productId,comandaId, cuisine) {
|
||||
obs = document.getElementById('obs');
|
||||
if(cuisine == 'ggg'){
|
||||
var obs = openModalObs();
|
||||
}else{
|
||||
fetch(`/comandas/addProduct${productId}/${comandaId}`, {
|
||||
method: 'GET',
|
||||
|
||||
// if (cuisine === 'ggg') {
|
||||
// openModalObs();
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Mostra estado de carregamento
|
||||
Swal.update({
|
||||
title: '<span style="color: white;">Adicionando produto...</span>',
|
||||
});
|
||||
|
||||
// Requisição POST
|
||||
const response = await fetch(`/comandas/product=${productId}/comanda=${comandaId}/`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'}
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': csrfToken
|
||||
},
|
||||
body: JSON.stringify({
|
||||
product_id: productId,
|
||||
comanda_id: comandaId
|
||||
})
|
||||
.then(function(response) {
|
||||
return response.text();
|
||||
}).then(function(text) {
|
||||
var listProductsBalcaoElement = document.getElementById("list-products-comanda");
|
||||
listProductsBalcaoElement.innerHTML = text;
|
||||
})
|
||||
showToastAdd('Produto adicionado com sucesso!😁','success');
|
||||
});
|
||||
|
||||
// Trata resposta
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
throw new Error(errorData.message || `Erro HTTP: ${response.status}`);
|
||||
}
|
||||
|
||||
const result = await response.text();
|
||||
|
||||
// Atualiza a lista de produtos
|
||||
const listElement = document.getElementById("list-products-comanda");
|
||||
if (listElement) {
|
||||
listElement.innerHTML = result;
|
||||
}
|
||||
|
||||
// Feedback de sucesso
|
||||
Swal.update({
|
||||
title: '<span style="color: green;">Produto adicionado! 😁</span>',
|
||||
});
|
||||
|
||||
// Reseta após 2.5 segundos
|
||||
setTimeout(() => {
|
||||
Swal.update({
|
||||
title: '<span style="color: white;">Adicionar Produto</span>'
|
||||
});
|
||||
}, 2500);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erro:', error);
|
||||
|
||||
// Feedback de erro
|
||||
Swal.update({
|
||||
title: '<span style="color: red;">Falha ao adicionar!</span>',
|
||||
html: `<div style="color: white; margin-top: 10px;">
|
||||
${error.message || 'Erro desconhecido'}
|
||||
</div>`,
|
||||
icon: 'error',
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function taxa(){
|
||||
|
||||
Reference in New Issue
Block a user